ArrowBehavior.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  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. // Update is called once per frame
  53. void Update()
  54. {
  55. if (!_gamingManager.IsGamePaused())
  56. {
  57. if (!bUsePhysics)
  58. {
  59. gameObject.transform.position = gameObject.transform.position + Direction_Kinematic * Time.deltaTime * Speed_Kinematic;
  60. }
  61. else {
  62. if (spawnType == SpawnType.bullet) {
  63. // 检测碰撞
  64. CheckCollision();
  65. // 更新位置
  66. previousPosition = transform.position;
  67. }
  68. }
  69. Lifetime += Time.deltaTime;
  70. if (Lifetime >= MissShootTime)
  71. {
  72. if (!bHit)
  73. {
  74. OnMissShoot.Invoke();
  75. }
  76. }
  77. if (Lifetime > LifetimeLimit)
  78. {
  79. Destroy(gameObject);
  80. //消除特效部分
  81. if (bulletHole) Destroy(bulletHole);
  82. }
  83. }
  84. }
  85. public void HitAFruit()
  86. {
  87. bHit = true;
  88. }
  89. void OnTriggerEnter(Collider other)
  90. {
  91. if (other.gameObject.tag == "StaticCollisionScene")
  92. {
  93. Rigidbody rb = gameObject.GetComponent<Rigidbody>();
  94. rb.isKinematic = true;
  95. rb.velocity = Vector3.zero;
  96. }
  97. }
  98. void CheckCollision()
  99. {
  100. RaycastHit hit;
  101. Vector3 direction = transform.position - previousPosition;
  102. float distance = direction.magnitude;
  103. if (Physics.Raycast(previousPosition, direction, out hit, distance, hitLayers))
  104. {
  105. // 确定碰撞点和法线
  106. Vector3 hitPoint = hit.point;
  107. Vector3 hitNormal = hit.normal;
  108. Transform hitTransform = hit.transform; // 获取碰撞物体的Transform
  109. // 生成弹坑
  110. CreateBulletHole(hitPoint, hitNormal, hitTransform);
  111. // 可选:销毁子弹或其他处理
  112. //Destroy(gameObject);
  113. }
  114. }
  115. void CreateBulletHole(Vector3 position, Vector3 normal, Transform parentTransform)
  116. {
  117. if (bulletHolePrefab != null)
  118. {
  119. // 实例化弹坑预制体
  120. bulletHole = Instantiate(bulletHolePrefab, position, Quaternion.LookRotation(normal));
  121. // 将弹坑作为子对象附加到被击中的对象上
  122. bulletHole.transform.SetParent(parentTransform);
  123. // 调整弹坑的方向,使其面向摄像机
  124. // bulletHole.transform.rotation = Quaternion.FromToRotation(Vector3.forward, -normal);
  125. // 确保弹坑贴在表面
  126. bulletHole.transform.position = position + normal * 0.01f;
  127. }
  128. }
  129. }