Zer0Cool Geschrieben 15. August 2020 Melden Share Geschrieben 15. August 2020 Falls es jemand gebrauchen kann, hier eine kleine Klasse die den Spieler mehrere zuvor zugewiesene Ziele betrachten lässt. Der Spieler dreht dabei seinen Körper und seinen Kopf in Richtung des Ziels welches am besten mit seiner Sichtlinie übereinstimmt. Die Distanz des Ziels wird dabei ebenfalls mit betrachtet, allerdings nur sehr rudimentär. Ich habe noch zusätzlich eingebaut, dass der Spieler seinen rechten Arm in Richtung des aktuellen Ziels bewegt (lässt sich deaktivieren über eine Property). using UnityEngine; using System; using System.Collections; [RequireComponent(typeof(Animator))] public class IKControl : MonoBehaviour { public Transform[] lookObj = null; public float weightDamping = 1.5f; public float maxDistance = 10f; public bool RightHandToTarget = true; private Animator animator; private Transform lastPrimaryTarget; private Quaternion savedRotation; private float lerpEndDistance = 0.1f; private float finalLookWeight = 0; private bool transitionToNextTarget = false; void Start() { animator = GetComponent<Animator>(); } // Callback for calculating IK void OnAnimatorIK() { if (lookObj != null) { Transform primaryTarget = null; float closestLookWeight = 0; // Here we find the target which is closest (by angle) to the players view line foreach (Transform target in lookObj) { Vector3 lookAt = target.position - transform.position; lookAt.y = 0f; // Filter out all objects that are too far away if (lookAt.magnitude > maxDistance) continue; // Find best matching object to the players view line float dotProduct = Vector3.Dot(new Vector3(transform.forward.x, 0f, transform.forward.z).normalized, lookAt.normalized); float lookWeight = Mathf.Clamp(dotProduct, 0f, 1f); if (lookWeight > closestLookWeight) { closestLookWeight = lookWeight; primaryTarget = target; } } if (primaryTarget != null) { if ((lastPrimaryTarget != null) && (lastPrimaryTarget != primaryTarget) && (finalLookWeight > 0f)) { // Here we start a new transition because the player looks already to a target but // we have found another target the player should look at transitionToNextTarget = true; } } // The player is in a neutral look position but has found a new target if ((primaryTarget != null) && !transitionToNextTarget) { lastPrimaryTarget = primaryTarget; finalLookWeight = Mathf.Lerp(finalLookWeight, closestLookWeight, Time.deltaTime * weightDamping); float bodyWeight = finalLookWeight * .75f; animator.SetLookAtWeight(finalLookWeight, bodyWeight, 1f); animator.SetLookAtPosition(primaryTarget.position); if (RightHandToTarget) { Vector3 relativePos = primaryTarget.position - transform.position; Quaternion rotationtoTarget = Quaternion.LookRotation(relativePos, Vector3.up); animator.SetIKRotationWeight(AvatarIKGoal.RightHand, finalLookWeight); animator.SetIKRotation(AvatarIKGoal.RightHand, rotationtoTarget); animator.SetIKPositionWeight(AvatarIKGoal.RightHand, finalLookWeight* 0.5f * closestLookWeight); animator.SetIKPosition(AvatarIKGoal.RightHand, primaryTarget.position); } } // Let the player smoothly look away from the last target to the neutral look position if ((primaryTarget == null && lastPrimaryTarget != null) || transitionToNextTarget) { finalLookWeight = Mathf.Lerp(finalLookWeight, 0f, Time.deltaTime * weightDamping); float bodyWeight = finalLookWeight * .75f; animator.SetLookAtWeight(finalLookWeight, bodyWeight, 1f); animator.SetLookAtPosition(lastPrimaryTarget.position); if (RightHandToTarget) { Vector3 relativePos = lastPrimaryTarget.position - transform.position; Quaternion rotationtoTarget = Quaternion.LookRotation(relativePos, Vector3.up); animator.SetIKRotationWeight(AvatarIKGoal.RightHand, finalLookWeight); animator.SetIKRotation(AvatarIKGoal.RightHand, rotationtoTarget); animator.SetIKPositionWeight(AvatarIKGoal.RightHand, finalLookWeight*0.5f * closestLookWeight); animator.SetIKPosition(AvatarIKGoal.RightHand, lastPrimaryTarget.position); } if (finalLookWeight < lerpEndDistance) { transitionToNextTarget = false; finalLookWeight = 0f; lastPrimaryTarget = null; } } } } } Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.