using System.Collections; using System.Collections.Generic; using UnityEngine; public enum SpawnType { arrow, bullet } public class ArrowBehavior : MonoBehaviour { private static GamingManager _gamingManager; private bool bUsePhysics; private Vector3 Direction_Kinematic; private float Speed_Kinematic; private float Lifetime = 0.0f; private const float LifetimeLimit = 15f; private const float MissShootTime = 3f; private bool bHit = false; public delegate void MissShoot(); public event MissShoot OnMissShoot; public SpawnType spawnType = SpawnType.arrow; public GameObject bulletHolePrefab; // 弹坑预制体 public LayerMask hitLayers; // 可以碰撞的图层 private Vector3 previousPosition; private GameObject bulletHole; // Start is called before the first frame update void Start() { _gamingManager = GameObject.Find("GameManager").GetComponent(); if (spawnType == SpawnType.bullet) { previousPosition = transform.position; } } public void Init(float speed, Vector3 dir, bool use_physics,bool useGravity = true) { bUsePhysics = use_physics; Rigidbody rb = gameObject.GetComponent(); if (bUsePhysics) { rb.useGravity = useGravity;// true; rb.isKinematic = false; rb.velocity = dir * speed; } else { rb.useGravity = useGravity;// = false; rb.isKinematic = true; rb.velocity = Vector3.zero; Speed_Kinematic = speed; Direction_Kinematic = dir; } } // Update is called once per frame void Update() { if (!_gamingManager.IsGamePaused()) { if (!bUsePhysics) { gameObject.transform.position = gameObject.transform.position + Direction_Kinematic * Time.deltaTime * Speed_Kinematic; } else { if (spawnType == SpawnType.bullet) { // 检测碰撞 CheckCollision(); // 更新位置 previousPosition = transform.position; } } Lifetime += Time.deltaTime; if (Lifetime >= MissShootTime) { if (!bHit) { OnMissShoot.Invoke(); } } if (Lifetime > LifetimeLimit) { Destroy(gameObject); //消除特效部分 if (bulletHole) Destroy(bulletHole); } } } public void HitAFruit() { bHit = true; } void OnTriggerEnter(Collider other) { if (other.gameObject.tag == "StaticCollisionScene") { Rigidbody rb = gameObject.GetComponent(); rb.isKinematic = true; rb.velocity = Vector3.zero; } } void CheckCollision() { RaycastHit hit; Vector3 direction = transform.position - previousPosition; float distance = direction.magnitude; if (Physics.Raycast(previousPosition, direction, out hit, distance, hitLayers)) { // 确定碰撞点和法线 Vector3 hitPoint = hit.point; Vector3 hitNormal = hit.normal; Transform hitTransform = hit.transform; // 获取碰撞物体的Transform // 生成弹坑 CreateBulletHole(hitPoint, hitNormal, hitTransform); // 可选:销毁子弹或其他处理 //Destroy(gameObject); } } void CreateBulletHole(Vector3 position, Vector3 normal, Transform parentTransform) { if (bulletHolePrefab != null) { // 实例化弹坑预制体 bulletHole = Instantiate(bulletHolePrefab, position, Quaternion.LookRotation(normal)); // 将弹坑作为子对象附加到被击中的对象上 bulletHole.transform.SetParent(parentTransform); // 调整弹坑的方向,使其面向摄像机 // bulletHole.transform.rotation = Quaternion.FromToRotation(Vector3.forward, -normal); // 确保弹坑贴在表面 bulletHole.transform.position = position + normal * 0.01f; } } }