如何使玩家看在多个目标取决于最近的目标使用逆运动学(IK)?



在lookObjects中,我有两个立方体,每个立方体都以不同的速度围绕玩家旋转,但玩家只会查看lookObjects列表中的第二个立方体,而不会查看第一个立方体。

我想让玩家知道根据最近的一个在lookObjects之间切换,因为现在即使第二个立方体在玩家后面,他也没有看它,它也不会切换到玩家前面的第一个立方体。

逻辑应该是,如果其中一个立方体在玩家视线之外,如果另一个在玩家视线内,则切换到另一个。

  • 为什么它不在lookObjects之间切换?

  • 如果两个立方体(lookObjects)都在玩家面前该怎么办?如何决定看哪一个?这种情况下的逻辑应该是什么?

代码附在播放器上:

using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
[RequireComponent(typeof(Animator))]
public class IKTests : MonoBehaviour
{
public Transform finger;
public List<Transform> lookObjects = new List<Transform>();
public float weightDamping = 1.5f;
private Animator animator;
private Transform lastPrimaryTarget;
private float lerpEndDistance = 0.1f;
private float finalLookWeight = 0;
private bool transitionToNextTarget = false;
void Start()
{
animator = GetComponent<Animator>();
}
private void Update()
{

}
private void OnDrawGizmos()
{
if (finger != null && lookObjects != null && lookObjects.Count > 0)
{
Gizmos.color = Color.green;
Gizmos.DrawLine(finger.position, lookObjects[0].position);
}
}
// Callback for calculating IK
void OnAnimatorIK()
{
if (lookObjects != 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 lookObjects)
{
Vector3 lookAt = target.position - transform.position;
lookAt.y = 0f;
float dotProduct = Vector3.Dot(new Vector3(transform.forward.x, 0f, transform.forward.z).normalized, lookAt.normalized);
float lookWeight = dotProduct;
closestLookWeight = float.MinValue;
if (lookWeight > closestLookWeight)
{
primaryTarget = target;
}
animator.SetIKPositionWeight(AvatarIKGoal.RightHand, 1);
animator.SetIKRotationWeight(AvatarIKGoal.RightHand, 1);
animator.SetIKPosition(AvatarIKGoal.RightHand, target.position);
animator.SetIKRotation(AvatarIKGoal.RightHand, target.rotation);
}
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(0.5f, 0.5f, 1f);//finalLookWeight, bodyWeight, 1f);
animator.SetLookAtPosition(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(0.5f, 0.5f, 1f);//finalLookWeight, bodyWeight, 1f);
animator.SetLookAtPosition(lastPrimaryTarget.position);
if (finalLookWeight < lerpEndDistance)
{
transitionToNextTarget = false;
finalLookWeight = 0f;
lastPrimaryTarget = null;
}
}
}
}
}

创建for循环在每次变换上使用Vector3.Distance(Transform A, Transform B)来获得外观顺序然后可以使用transform.LookAt(Transform target)查看对象

相关内容

最新更新