C# 如何在Unity 3d中跳过固定距离?
我有一个控制器,可以沿对角线移动我的对象。左箭头应将玩家向前向左移动45度,右箭头向右移动45度。我想将玩家移动到相对其当前位置。现在它相对于点(0,0,0)移动 我的代码:C# 如何在Unity 3d中跳过固定距离?,c#,unity3d,C#,Unity3d,我有一个控制器,可以沿对角线移动我的对象。左箭头应将玩家向前向左移动45度,右箭头向右移动45度。我想将玩家移动到相对其当前位置。现在它相对于点(0,0,0)移动 我的代码: public class JollyJumper : MonoBehaviour { protected CharacterController control; public float fTime = 1.5f; // Hop time public float fRange = 5.0f;
public class JollyJumper : MonoBehaviour {
protected CharacterController control;
public float fTime = 1.5f; // Hop time
public float fRange = 5.0f; // Max dist from origin
public float fHopHeight = 2.0f; // Height of hop
private Vector3 v3Dest;
private Vector3 v3Last;
private float fTimer = 0.0f;
private bool moving = false;
private int number= 0;
private Vector2 direction;
public virtual void Start () {
control = GetComponent<CharacterController>();
if(!control){
Debug.LogError("No Character Controller");
enabled=false;
}
}
void Update () {
if (fTimer >= fTime&& moving) {
var playerObject = GameObject.Find("Player");
v3Last = playerObject.transform.position;
Debug.Log(v3Last);
v3Dest = direction *fRange;
//v3Dest = newVector* fRange + v3Last;
v3Dest.z = v3Dest.y;
v3Dest.y = 0.0f;
fTimer = 0.0f;
moving = false;
}
if(Input.GetKeyDown(KeyCode.LeftArrow)){
moving = true;
direction = new Vector2(1.0f, 1.0f);
number++;
}
if(Input.GetKeyDown(KeyCode.RightArrow)){
moving = true;
direction = new Vector2(-1.0f, 1.0f);
number++;
}
if(moving){
Vector3 v3T = Vector3.Lerp (v3Last, v3Dest, fTimer / fTime);
v3T.y = Mathf.Sin (fTimer/fTime * Mathf.PI) * fHopHeight;
control.transform.position = v3T;
fTimer += Time.deltaTime;
}
}
}
public-class-JollyJumper:monobhavior{
保护字符控制器控制;
公共浮点fTime=1.5f;//跃点时间
公共浮点数fRange=5.0f;//与原点的最大距离
公共浮球FhoPhight=2.0f;//跃点高度
私有向量3 v3Dest;
私有向量3 v3Last;
专用浮动fTimer=0.0f;
私有布尔移动=假;
私有整数=0;
专用矢量2方向;
公共虚拟空开始(){
控件=GetComponent();
如果(!控制){
LogError(“无字符控制器”);
启用=错误;
}
}
无效更新(){
如果(fTimer>=fTime&&moving){
var playerObject=GameObject.Find(“玩家”);
v3Last=播放对象.transform.position;
Debug.Log(v3Last);
v3Dest=方向*法兰;
//v3Dest=newVector*fRange+v3Last;
v3Dest.z=v3Dest.y;
v3Dest.y=0.0f;
fTimer=0.0f;
移动=假;
}
if(Input.GetKeyDown(KeyCode.LeftArrow)){
移动=真;
方向=新矢量2(1.0f,1.0f);
数字++;
}
if(Input.GetKeyDown(KeyCode.RightArrow)){
移动=真;
方向=新矢量2(-1.0f,1.0f);
数字++;
}
如果(移动){
vector3v3t=Vector3.Lerp(v3Last、v3Dest、fTimer/fTime);
v3T.y=数学Sin(fTimer/fTime*Mathf.PI)*fHphight;
control.transform.position=v3T;
fTimer+=Time.deltaTime;
}
}
}
如何解决这个问题?有什么想法吗?非常感谢 简单的回答是:您硬编码了两个要跳转到的位置:点(1,1)和(-1,1)。您应该在每次开始跳跃时创建新向量。更换每个
direction = new Vector2(1.0f, 1.0f);
这一行:
v3Dest = transform.position + new Vector3(1.0f, 0, 1) * fRange;
它应该会起作用
当我谈到这个问题时,我想指出一些其他的事情:
- 每次跳转后都会出现大量浮点错误。请注意,在您的代码中,
永远不会等于v3T
(您永远不会真正到达目的地),因为您之前切换了v3Dest
标志。跳转结束时,应明确将位置设置为移动
v3Dest
- 您正在检查跳转计时器等每一帧。一个更明智的解决办法是
- 使用正弦曲线作为跳跃曲线,看起来不错,但使用抛物线在概念上更为正确
- 现在可以开始下一次空中跳跃(我不确定是否有意)
using System.Collections;
using UnityEngine;
public class Jumper : MonoBehaviour
{
#region Set in editor;
public float jumpDuration = 0.5f;
public float jumpDistance = 3;
#endregion Set in editor;
private bool jumping = false;
private float jumpStartVelocityY;
private void Start()
{
// For a given distance and jump duration
// there is only one possible movement curve.
// We are executing Y axis movement separately,
// so we need to know a starting velocity.
jumpStartVelocityY = -jumpDuration * Physics.gravity.y / 2;
}
private void Update()
{
if (jumping)
{
return;
}
else if (Input.GetKeyDown(KeyCode.LeftArrow))
{
// Warning: this will actually move jumpDistance forward
// and jumpDistance to the side.
// If you want to move jumpDistance diagonally, use:
// Vector3 forwardAndLeft = (transform.forward - transform.right).normalized * jumpDistance;
Vector3 forwardAndLeft = (transform.forward - transform.right) * jumpDistance;
StartCoroutine(Jump(forwardAndLeft));
}
else if (Input.GetKeyDown(KeyCode.RightArrow))
{
Vector3 forwardAndRight = (transform.forward + transform.right) * jumpDistance;
StartCoroutine(Jump(forwardAndRight));
}
}
private IEnumerator Jump(Vector3 direction)
{
jumping = true;
Vector3 startPoint = transform.position;
Vector3 targetPoint = startPoint + direction;
float time = 0;
float jumpProgress = 0;
float velocityY = jumpStartVelocityY;
float height = startPoint.y;
while (jumping)
{
jumpProgress = time / jumpDuration;
if (jumpProgress > 1)
{
jumping = false;
jumpProgress = 1;
}
Vector3 currentPos = Vector3.Lerp(startPoint, targetPoint, jumpProgress);
currentPos.y = height;
transform.position = currentPos;
//Wait until next frame.
yield return null;
height += velocityY * Time.deltaTime;
velocityY += Time.deltaTime * Physics.gravity.y;
time += Time.deltaTime;
}
transform.position = targetPoint;
yield break;
}
}简单的回答是:您硬编码了两个要跳转到的位置:点(1,1)和(-1,1)。您应该在每次开始跳跃时创建新向量。更换每个
direction = new Vector2(1.0f, 1.0f);
这一行:
v3Dest = transform.position + new Vector3(1.0f, 0, 1) * fRange;
它应该会起作用
当我谈到这个问题时,我想指出一些其他的事情:
- 每次跳转后都会出现大量浮点错误。请注意,在您的代码中,
永远不会等于v3T
(您永远不会真正到达目的地),因为您之前切换了v3Dest
标志。跳转结束时,应明确将位置设置为移动
v3Dest
- 您正在检查跳转计时器等每一帧。一个更明智的解决办法是
- 使用正弦曲线作为跳跃曲线,看起来不错,但使用抛物线在概念上更为正确
- 现在可以开始下一次空中跳跃(我不确定是否有意)
using System.Collections;
using UnityEngine;
public class Jumper : MonoBehaviour
{
#region Set in editor;
public float jumpDuration = 0.5f;
public float jumpDistance = 3;
#endregion Set in editor;
private bool jumping = false;
private float jumpStartVelocityY;
private void Start()
{
// For a given distance and jump duration
// there is only one possible movement curve.
// We are executing Y axis movement separately,
// so we need to know a starting velocity.
jumpStartVelocityY = -jumpDuration * Physics.gravity.y / 2;
}
private void Update()
{
if (jumping)
{
return;
}
else if (Input.GetKeyDown(KeyCode.LeftArrow))
{
// Warning: this will actually move jumpDistance forward
// and jumpDistance to the side.
// If you want to move jumpDistance diagonally, use:
// Vector3 forwardAndLeft = (transform.forward - transform.right).normalized * jumpDistance;
Vector3 forwardAndLeft = (transform.forward - transform.right) * jumpDistance;
StartCoroutine(Jump(forwardAndLeft));
}
else if (Input.GetKeyDown(KeyCode.RightArrow))
{
Vector3 forwardAndRight = (transform.forward + transform.right) * jumpDistance;
StartCoroutine(Jump(forwardAndRight));
}
}
private IEnumerator Jump(Vector3 direction)
{
jumping = true;
Vector3 startPoint = transform.position;
Vector3 targetPoint = startPoint + direction;
float time = 0;
float jumpProgress = 0;
float velocityY = jumpStartVelocityY;
float height = startPoint.y;
while (jumping)
{
jumpProgress = time / jumpDuration;
if (jumpProgress > 1)
{
jumping = false;
jumpProgress = 1;
}
Vector3 currentPos = Vector3.Lerp(startPoint, targetPoint, jumpProgress);
currentPos.y = height;
transform.position = currentPos;
//Wait until next frame.
yield return null;
height += velocityY * Time.deltaTime;
velocityY += Time.deltaTime * Physics.gravity.y;
time += Time.deltaTime;
}
transform.position = targetPoint;
yield break;
}
}您能给我一些代码片段吗?我在编程方面有经验,但在Unity3d方面没有经验。只需在Unity inspector中将控制器拖放到播放器即可。或者设置
controller.transform.parent=player.transform
,如果您在运行时创建了其中任何一个。您好,很抱歉,我编辑了问题以使其更清楚。我就是不能让球员左右跳跃。我必须不断增加v3dest,因为palyer是相对于(0,0,0)移动的,而不是相对于他自己。好了,现在我迷路了。-这是2D还是3D场景(你提到向前跳和向左跳(意思是3D),但你的代码表明这是2D)-你所说的“相对于他自己”是什么意思?你不能相对于自己移动,它没有物理意义为什么不更换控制器。速度不适合你的需要?嗨。这是一个3D场景。我在做一种平板状的漏斗。但平台形式与左前和右前的距离总是相同的。现在,如果我设置v3Dest=directionnumberfRange,那么玩家将继续向左向前跳跃。但他不会向右转和前进。甚至可以使用这种形式的代码吗?如果我使用v3Dest=Random.insideUnitCircle*fRange;然后,当我按下箭头按钮时,玩家随机地跳来跳去。Random.insideUnitCircle只返回一个向量2。所以我想我可以用(1,1)表示右边,(1,-1)表示左边。你能给我一些代码片段吗?我在编程方面有经验,但在Unity3d方面没有经验。只需在Unity inspector中将控制器拖放到播放器即可。或者设置controller.transform.parent=player.transform
,如果您在运行时创建了其中任何一个。您好,很抱歉,我编辑了问题以使其更清楚。我就是不能让球员左右跳跃。我必须不断增加v3dest,因为palyer是相对于(0,0,0)移动的,而不是相对于他自己。好了,现在我迷路了。-是2D还是3D场景(你提到的是向前跳和向左跳