[英]Why when moving an object towards a target if the target is far away the object move very fast but if the target is close it's moving slower?
我希望它像近距離物體一樣移動得更慢。
小立方體從玩家手中移動到右邊的大立方體。 右邊的大立方體是目標。
這是播放器根目錄 object,附有腳本,投擲速度設置為 0.5f
這是更新中的腳本,我正在調用 ThrowObject 方法:
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 GameObject objToThrow;
public Text text;
public Text textMultiLine;
public float weightDamping = 1.5f;
public float maxDistance = 10f;
public bool RightHandToTarget = true;
public float throwSpeed;
private List<InteractableItem> allDetectedItems;
private Animator animator;
private InteractableItem lastPrimaryTarget;
private Quaternion savedRotation;
private float lerpEndDistance = 0.1f;
private float finalLookWeight = 0;
private bool transitionToNextTarget = false;
private InteractableItem target;
private bool throwObj = false;
void Start()
{
animator = GetComponent<Animator>();
allDetectedItems = new List<InteractableItem>();
}
// 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
allDetectedItems.Clear();
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, 0f, 1f);
if (lookWeight > 0.1f && lookWeight > closestLookWeight)
{
closestLookWeight = lookWeight;
primaryTarget = target;
allDetectedItems.Add(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 * 1f * closestLookWeight);
animator.SetIKPosition(AvatarIKGoal.RightHand, primaryTarget.transform.position);
// -> new code block
if (finalLookWeight > 0.95f) // here you can play with a value between 0.95f -> 1.0f
{
// call your funtion to shoot something here
throwObj = true;
target = primaryTarget;
}
}
}
// 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.transform.position);
if (RightHandToTarget)
{
Vector3 relativePos = lastPrimaryTarget.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, lastPrimaryTarget.transform.position);
}
if (finalLookWeight < lerpEndDistance)
{
transitionToNextTarget = false;
finalLookWeight = 0f;
lastPrimaryTarget = null;
}
}
// Show primary object found by the player
if (primaryTarget != null) text.text = "Item found: " + primaryTarget.description;
else text.text = "Item found: none";
// Show all objects found by the player
if (allDetectedItems.Count > 0)
{
string result = "";
foreach (InteractableItem item in allDetectedItems)
{
result += item.description + "\n";
}
textMultiLine.text = result;
}
else
{
textMultiLine.text = "No items found.";
}
}
}
private void ThrowObject()
{
objToThrow.transform.position = Vector3.Lerp(objToThrow.transform.position, target.transform.position, throwSpeed * Time.deltaTime);
}
private void Update()
{
if (throwObj == true)
{
ThrowObject();
}
}
}
問題是當玩家面對巨大的遠方太空船時,立方體正在向太空船移動,它移動得非常快,我幾乎看不到立方體在移動。 不確定為什么它移動到近距離目標時緩慢而平滑,但移動到遠距離目標時卻非常快?
對於移動,您使用 function Vector3.Lerp(Vector3 a, Vector3 b, float t) 。 它使用以下公式找到a
和b
之間的交集值formula: a + (b - a) * t
。
讓我們假設 z 位置無關緊要,並且 main object position [0,0]讓我們看看以下情況:
float t
從起點 position 移動到目標 position。 讓我們計算主對象的 position 如果t
是,例如: 0.1
, 0.2
, 0.3
(顯然如果它是0
主對象的 position 是開始 position,如果它是1
主對象的 8811773473171817 FOR3MU:3817 FOR3MU : 3817 (b - a) * t 1) [0,0] + ([10,10] - [0,0]) * 0.1 = [0,0] + [10,10]*0.1 = [0,0] + [1,1] = [1,1]
2) [0,0] + ([10,10] - [0,0]) * 0.2 = [0,0] + [10,10]*0.2 = [0,0] + [2,2] = [2,2]
3) [0,0] + ([10,10] - [0,0]) * 0.3 = [0,0] + [10,10]*0.3 = [0,0] + [3,3] = [3,3]
我們得到,將變量t
改變0.1會導致 position 改變[1,1]個單位。
t
原樣: 0.1 and 0.2 and 0.3
。 計數:公式:a + (b - a) * t 1) [0,0] + ([500,500] - [0,0]) * 0.1 = [0,0] + [500,500]*0.1 = [0,0] + [50,50] = [50,50]
2) [0,0] + ([500,500] - [0,0]) * 0.2 = [0,0] + [500,500]*0.2 = [0,0] + [100,100] = [100,100]
3) [0,0] + ([500,500] - [0,0]) * 0.3 = [0,0] + [500,500]*0.3 = [0,0] + [150,150] = [150,150]
這里將變量t
改變0.1會導致 position 改變[50,50]個單位。
因此,對象之間的距離越大,主對象的 position 變化越快。
嗯,這是對你做錯了什么的解釋。 現在決定:
您應該使用 function transform.Translate(Vector3 translation) 。
這個 function 在參數 Vector3 translate 的方向移動 object。 當然,如果平移等於 [1,0,0],則 object 移動到正 x,如果 [-1,0,0] - 移動到負 x,如果 [0,1,0] - 移動到正 y,如果 [0 ,-1,0] - 負 y 等等。
如何獲得此 Vector3 translation
? 您必須從目標 position 中減去對象的 position。然后您應該對其進行歸一化(以便值不大於 1 且不小於 0)。 代碼看起來是這樣的:
Vector3 dir; // direction of moving. This parameter will be given to the function Translate()
GameObject targetPosition; // Target position
float speed; // The speed of moving. Recommended to be set from inspector
private void ThrowObject () {
dir = targetPosition - transform.position;
transform.Traslate(dir.normalized*Time.deltaTime*speed);
}
private void Update () {
ThrowObject();
}
PS 我們將dir
乘以Time.deltaTime
使移動速度在快速和慢速計算機(平板電腦、手機...)上相同
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.