问题描述
using UnityEngine;
using System;
using System.Collections;
using UnityEngine.UI;
using System.Collections.Generic;
[RequireComponent(typeof(Animator))]
public class IKControl : MonoBehavIoUr
{
public InteractableItem[] lookObj = null;
public Text text;
public float weightdamping = 1.5f;
public float maxdistance = 10f;
public bool RightHandToTarget = true;
private Animator animator;
private InteractableItem 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)
{
InteractableItem primaryTarget = null;
float closestLookWeight = 0;
// Here we find the target which is closest (by angle) to the players view line
foreach (InteractableItem target in lookObj)
{
Vector3 lookAt = target.transform.position - transform.position;
lookAt.y = 0f;
// Filter out all objects that are too far away
//if (lookAt.magnitude > maxdistance) continue;
if (lookAt.magnitude > target.distance) continue;
float dotProduct = Vector3.Dot(new Vector3(transform.forward.x,0f,transform.forward.z).normalized,lookAt.normalized);
float lookWeight = Mathf.Clamp(dotProduct,1f);
if (lookWeight > 0.1f && 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);
finalLookWeight = Mathf.Lerp(finalLookWeight,1f,Time.deltaTime * weightdamping);
float bodyWeight = finalLookWeight * .75f;
animator.SetLookAtWeight(finalLookWeight,bodyWeight,1f);
animator.SetLookAtPosition(primaryTarget.transform.position);
if (RightHandToTarget)
{
Vector3 relativePos = primaryTarget.transform.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.transform.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,1f);
animator.SetLookAtPosition(lastPrimaryTarget.transform.position);
if (RightHandToTarget)
{
Vector3 relativePos = lastPrimaryTarget.transform.position - transform.position;
Quaternion rotationtoTarget = Quaternion.LookRotation(relativePos,lastPrimaryTarget.transform.position);
}
if (finalLookWeight < lerpEnddistance)
{
transitionToNextTarget = false;
finalLookWeight = 0f;
lastPrimaryTarget = null;
}
}
// Show found object by the player
if (primaryTarget != null)
{
text.text = primaryTarget.description;
}
else
{
text.text = "";
}
}
}
}
这是附加到每个可交互项对象的InteractableItem类:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class InteractableItem : MonoBehavIoUr
{
public float distance = 10f;
public string description = "";
}
现在我使用一个简单的字符串,然后在IKControl脚本中显示它:
if (primaryTarget != null)
{
text.text = primaryTarget.description;
}
else
{
text.text = "";
}
但是有两个问题:
-
在检查器中的字符串中键入描述不是一个好主意,因为文本很快就会脱离字符串字段。
-
左下角游戏视图窗口中的文本太左,取决于我输入的描述文本多少,该文本会从屏幕上消失。我需要一直更改ui文本的宽度,但这不是解决方案。
多维数据集是可交互的项目:
也许每个项目也只使用一个字符串来使用ui文本?还是另一个文本容器?然后如何在IKControl脚本中使用它?
解决方法
假设我正确理解了您的要求,对于大多数描述,您都可以制作一个具有[TextArea]
属性的公共字符串。您可以很容易地找到complete list of attributes,它们很多,而且如果正确使用它们,您可以在检查器中开始做一些非常酷的事情。