BITFALL/Assets/Artists/Scripts/BulletManager/BulletService.cs

147 lines
5.3 KiB
C#
Raw Normal View History

2023-06-08 14:09:50 +08:00
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using BITKit;
using BITKit.Entities;
using BITKit.ObjectMaterial;
using Net.Client;
using Net.Component;
using Net.Serialize;
using Net.Config;
using Net.Event;
using Net.Server;
using Net.Share;
using Net.System;
using Cysharp.Threading.Tasks;
using Unity.Mathematics;
using UnityEngine.Animations;
namespace BITFALL
{
[System.Serializable]
public record InstanceBullet : SpawnBullet
{
public Vector3 currentPos;
public float currentSpeed = 64;
public BITBullet model;
}
public class BulletService : MonoBehaviour
{
public static Action<SpawnBullet> Spawn;
[Header(Constant.Header.Settings)]
public LayerMask layerMask;
[Header(Constant.Header.Prefabs)]
public ObjectMaterialScriptableObject defaultMaterial;
[Header(Constant.Header.Settings)]
public UnityPool<BITBullet> pool = new();
[Header(Constant.Header.InternalVariables)]
public List<InstanceBullet> instances = new();
void Start()
{
Spawn += SpawnBullet;
DI.Get<ClientBase>().AddRpcHandle(this);
}
void OnDestroy()
{
Spawn -= SpawnBullet;
}
void FixedUpdate()
{
instances = instances ?? new();
foreach (var bullet in instances.ToArray())
{
if (Physics.Raycast(bullet.currentPos, bullet.forward, out var raycastHit, bullet.currentSpeed * Time.fixedDeltaTime, layerMask))
{
var force = (raycastHit.point - (Vector3)bullet.pos).normalized * 64;
instances.TryRemove(bullet);
pool.Return(bullet.model);
if (raycastHit.transform.TryGetComponent<IDamagable>(out var damagable))
{
damagable.GiveDamage(new DamageMessage()
{
target = damagable.Entity,
hit = damagable,
damage = 30,
});
damagable.Rigidbody?.AddForceAtPositionAsync(force, raycastHit.point);
}
else
{
raycastHit.rigidbody?.AddForceAtPositionAsync(force, raycastHit.point);
}
List<string> tags = new()
{
"BulletHit",
};
if (raycastHit.transform.TryGetComponent<ITag>(out var tag))
{
tags.AddRange(tag.GetTags());
}
Location location = new()
{
position = raycastHit.point,
forward = raycastHit.normal,
};
var vfx = DI.Get<VFXService>().Spawn(location, tags.ToArray());
var constraint = vfx.gameObject.AddComponent<ParentConstraint>();
var sourceTransform = raycastHit.transform;
constraint.AddSource(new ConstraintSource()
{
sourceTransform = sourceTransform,
weight = 1,
});
Vector3 positionOffset = sourceTransform.InverseTransformPoint(raycastHit.point);
Quaternion rotationOffset = Quaternion.Inverse(sourceTransform.rotation) * transform.rotation;
constraint.SetTranslationOffset(0, positionOffset);
constraint.SetRotationOffset(0, rotationOffset.eulerAngles);
constraint.weight = 1;
constraint.constraintActive = true;
}
else if (bullet.currentSpeed <= 0)
{
instances.TryRemove(bullet);
}
else
{
bullet.currentSpeed -= bullet.startSpeed * Time.fixedDeltaTime;
bullet.currentPos += (Vector3)bullet.forward * (bullet.currentSpeed * Time.fixedDeltaTime);
bullet.model.transform.position = bullet.currentPos;
}
}
}
[Rpc]
async void RpcSpawnBullet(SpawnBullet x)
{
await UniTask.SwitchToMainThread();
var instance = pool.Get();
//BIT4Log.Log<BulletManager>($"客户端收到的:{x}");
InstanceBullet bullet = new()
{
initiator = x.initiator,
currentPos = x.pos,
pos = x.pos,
rot = x.rot,
forward = x.forward
};
//BIT4Log.Log<BulletManager>($"实例化的:{bullet}");
bullet.model = instance;
bullet.model.transform.SetPositionAndRotation(x.pos, x.rot);
bullet.model.transform.forward = x.forward;
instances.Add(bullet);
}
void SpawnBullet(SpawnBullet x)
{
//BIT4Log.Log<BulletManager>($"客户端发送的:{x}");
//DI.Get<ClientBase>().SendRT(nameof(RpcSpawnBullet), x);
//FGame.ClientAllRpc(nameof(RpcSpawnBullet), x);
//DI.Get<INetMessager>().Send<SpawnBullet>(x);
}
}
}