如何实现射线检测命中后带动画的游戏对象消失?
Got it, let's adjust your raycast script to trigger the target's animation first, then destroy the object once the animation finishes. Here's a straightforward approach with two reliable methods:
Method 1: Use Animation Events (Most Reliable)
This method lets you trigger destruction exactly when the animation ends, even if the animation's length or speed changes.
Step 1: Add a Helper Script to Your Target
Create a new script called TargetHandler and attach it to your Target GameObject:
using UnityEngine; public class TargetHandler : MonoBehaviour { // This method will be called by an animation event public void DestroyAfterAnimation() { Destroy(gameObject); } }
Step 2: Set Up the Animator
- Open your Animator Controller for the Target.
- Make sure you have a "Disappear" animation state (or whatever your vanish animation is named).
- Add a Trigger parameter named
Disappear(match this name in your raycast script later). - Set up a transition from your target's idle state to the Disappear state, using the
Disappeartrigger as the condition. - In the Animation window, open your Disappear animation clip. Move the playhead to the last frame of the animation, right-click the timeline, and select Add Event.
- In the event settings, select your
TargetHandlercomponent and choose theDestroyAfterAnimationmethod.
Step 3: Modify Your Raycast Script
Update the code on your gun to trigger the animation instead of immediately destroying the object:
using UnityEngine; public class GunScript : MonoBehaviour { public Camera fpsCam; public float range = 100f; void Update() { if (Input.GetMouseButtonDown(0)) // Assuming left click fires { RaycastHit hit; if (Physics.Raycast(fpsCam.transform.position, fpsCam.transform.forward, out hit, range)) { Debug.Log($"Hit: {hit.collider.tag} - {hit.collider.name}"); // Check if we hit the Robot collider, then get its parent Target GameObject targetObj = hit.collider.transform.parent.gameObject; Animator targetAnimator = targetObj.GetComponent<Animator>(); if (targetAnimator != null) { // Trigger the disappear animation targetAnimator.SetTrigger("Disappear"); } else { Debug.LogWarning("Target GameObject is missing an Animator component!"); // Fallback to immediate destroy if no animator exists Destroy(targetObj); } } } } }
Method 2: Delay Destroy by Animation Length
If you prefer not to use animation events, you can calculate the animation's length and delay destruction. Note this is less reliable if your animation has transitions or variable speed.
Modify your raycast script like this:
using UnityEngine; public class GunScript : MonoBehaviour { public Camera fpsCam; public float range = 100f; public string disappearAnimationName = "Disappear"; // Match your animation clip name void Update() { if (Input.GetMouseButtonDown(0)) { RaycastHit hit; if (Physics.Raycast(fpsCam.transform.position, fpsCam.transform.forward, out hit, range)) { Debug.Log($"Hit: {hit.collider.tag} - {hit.collider.name}"); GameObject targetObj = hit.collider.transform.parent.gameObject; Animator targetAnimator = targetObj.GetComponent<Animator>(); if (targetAnimator != null) { targetAnimator.SetTrigger("Disappear"); // Find the length of the disappear animation float animationLength = 0f; foreach (AnimationClip clip in targetAnimator.runtimeAnimatorController.animationClips) { if (clip.name == disappearAnimationName) { animationLength = clip.length; break; } } // Delay destruction until the animation finishes if (animationLength > 0) { Destroy(targetObj, animationLength); } else { Debug.LogWarning($"Could not find animation clip named {disappearAnimationName}!"); Destroy(targetObj); } } else { Debug.LogWarning("Target GameObject is missing an Animator component!"); Destroy(targetObj); } } } } }
Key Notes
- Make sure your Robot Capsule Collider has
IsTriggerdisabled (since we're usingPhysics.Raycastwhich detects non-trigger colliders). - Double-check that the parameter name in your Animator matches the one in your script (e.g.,
Disappear). - If your Target has multiple child objects, confirm that
hit.collider.transform.parentcorrectly points to the Target GameObject (adjust the parent hierarchy if needed).
内容的提问来源于stack exchange,提问作者MileHigh

