ArrowBehavior.cs 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public enum SpawnType {
  5. arrow,
  6. bullet
  7. }
  8. public class ArrowBehavior : MonoBehaviour
  9. {
  10. private static GamingManager _gamingManager;
  11. private bool bUsePhysics;
  12. private Vector3 Direction_Kinematic;
  13. private float Speed_Kinematic;
  14. private float Lifetime = 0.0f;
  15. private const float LifetimeLimit = 15f;
  16. private const float MissShootTime = 3f;
  17. private bool bHit = false;
  18. public delegate void MissShoot();
  19. public event MissShoot OnMissShoot;
  20. public SpawnType spawnType = SpawnType.arrow;
  21. public GameObject bulletHolePrefab; // 弹坑预制体
  22. public LayerMask hitLayers; // 可以碰撞的图层
  23. private Vector3 previousPosition;
  24. private GameObject bulletHole;
  25. // Start is called before the first frame update
  26. void Start()
  27. {
  28. _gamingManager = GameObject.Find("GameManager").GetComponent<GamingManager>();
  29. if (spawnType == SpawnType.bullet) {
  30. previousPosition = transform.position;
  31. }
  32. }
  33. public void Init(float speed, Vector3 dir, bool use_physics,bool useGravity = true)
  34. {
  35. bUsePhysics = use_physics;
  36. Rigidbody rb = gameObject.GetComponent<Rigidbody>();
  37. if (bUsePhysics)
  38. {
  39. rb.useGravity = useGravity;// true;
  40. rb.isKinematic = false;
  41. rb.velocity = dir * speed;
  42. }
  43. else
  44. {
  45. rb.useGravity = useGravity;// = false;
  46. rb.isKinematic = true;
  47. rb.velocity = Vector3.zero;
  48. Speed_Kinematic = speed;
  49. Direction_Kinematic = dir;
  50. }
  51. //如果是枪不用碰撞体
  52. if (GlobalData.MyDeviceMode == DeviceMode.Gun)
  53. Destroy(GetComponent<SphereCollider>());
  54. }
  55. // Update is called once per frame
  56. void Update()
  57. {
  58. if (!_gamingManager.IsGamePaused())
  59. {
  60. if (!bUsePhysics)
  61. {
  62. gameObject.transform.position = gameObject.transform.position + Direction_Kinematic * Time.deltaTime * Speed_Kinematic;
  63. }
  64. else {
  65. if (spawnType == SpawnType.bullet) {
  66. // 检测碰撞
  67. //CheckCollision();
  68. // 更新位置
  69. //previousPosition = transform.position;
  70. }
  71. }
  72. Lifetime += Time.deltaTime;
  73. if (Lifetime >= MissShootTime)
  74. {
  75. if (!bHit)
  76. {
  77. OnMissShoot.Invoke();
  78. }
  79. }
  80. if (Lifetime > LifetimeLimit)
  81. {
  82. Destroy(gameObject);
  83. //消除特效部分
  84. if (bulletHole) Destroy(bulletHole);
  85. }
  86. }
  87. }
  88. public void HitAFruit()
  89. {
  90. bHit = true;
  91. }
  92. void OnTriggerEnter(Collider other)
  93. {
  94. if (other.gameObject.tag == "StaticCollisionScene")
  95. {
  96. Rigidbody rb = gameObject.GetComponent<Rigidbody>();
  97. rb.isKinematic = true;
  98. rb.velocity = Vector3.zero;
  99. }
  100. }
  101. //void CheckCollision()
  102. //{
  103. // RaycastHit hit;
  104. // Vector3 direction = transform.position - previousPosition;
  105. // float distance = direction.magnitude;
  106. // Debug.DrawRay(transform.position, direction);
  107. // if (Physics.Raycast(transform.position, direction, out hit, distance , hitLayers))
  108. // {
  109. // // 确定碰撞点和法线
  110. // Vector3 hitPoint = hit.point;
  111. // Vector3 hitNormal = hit.normal;
  112. // Transform hitTransform = hit.transform; // 获取碰撞物体的Transform
  113. // if (hit.transform.tag == "StaticCollisionScene")
  114. // {
  115. // // 生成弹坑
  116. // CreateBulletHole(hitPoint, hitNormal, hitTransform);
  117. // }
  118. // if(hit.transform.tag == "Fruit") {
  119. // Debug.Log("hit.transform.tag :" + hit.transform.tag);
  120. // //处理水果分数
  121. // FruitBehavior fruitBehavior = hit.transform.GetComponent<FruitBehavior>();
  122. // Collider collider = GetComponent<Collider>();
  123. // fruitBehavior.OnHitCollision(collider);
  124. // }
  125. // // 可选:销毁子弹或其他处理
  126. // //Destroy(gameObject);
  127. // }
  128. // if (Input.GetKeyDown(KeyCode.Alpha1))
  129. // {
  130. // UnityEditor.EditorApplication.isPaused = true;
  131. // }
  132. // if (Input.GetKeyDown(KeyCode.Alpha2))
  133. // {
  134. // UnityEditor.EditorApplication.isPaused = false;
  135. // }
  136. //}
  137. /// <summary>
  138. /// 创建一个弹坑
  139. /// </summary>
  140. /// <param name="position"></param>
  141. /// <param name="normal"></param>
  142. /// <param name="parentTransform"></param>
  143. public void CreateBulletHole(Vector3 position, Vector3 normal, Transform parentTransform)
  144. {
  145. //停止运动
  146. Rigidbody rb = gameObject.GetComponent<Rigidbody>();
  147. rb.isKinematic = true;
  148. rb.velocity = Vector3.zero;
  149. if (bulletHolePrefab != null)
  150. {
  151. // 实例化弹坑预制体
  152. bulletHole = Instantiate(bulletHolePrefab, position, Quaternion.LookRotation(normal));
  153. // 将弹坑作为子对象附加到被击中的对象上
  154. bulletHole.transform.SetParent(parentTransform);
  155. // 调整弹坑的方向,使其面向摄像机
  156. // bulletHole.transform.rotation = Quaternion.FromToRotation(Vector3.forward, -normal);
  157. // 确保弹坑贴在表面
  158. bulletHole.transform.position = position + normal * 0.01f;
  159. }
  160. }
  161. }