147 lines
5.3 KiB
C#
147 lines
5.3 KiB
C#
|
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);
|
||
|
}
|
||
|
}
|
||
|
}
|