朝可移动物体靠近和震动

第一步:
朝物体靠近
首先我们做的是一个生物朝物体靠近,一般生物靠近都是要面朝物体的,因此我们先要让我们的生物旋转一定角度面朝我们的物体
旋转的脚本是:transform.rotation=Quaternion.Slerp(transform.rotation,Mark.transform.rotation,Speed*Time.deltaTime);
这里我们的一个难点是我们的Mark的旋转怎么写?我们的Mark是什么?我们是要朝向我们的目标物体
因此Mark.transform.rotation=Quaternion.LookRotation(内里填我们要朝向的那个向量);
Vector3 relativePos=Target.transform.position - transform.position;//这样我们的生物的朝向可以随时变化

因此综合下来就是:
if (Vector3.Distance(transform.position, Target.transform.position) > 0.1f)
{
Vector3 relativePos = Target.transform.position - transform.position;
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(relativePos), 0.1f);
transform.position += transform.forward * Speed * Time.deltaTime;
}

第二步:
上下震动但不能太生硬
我们想到上下震动可以用到
transform.position+=new Vector3(0,y,0);
我们需要y这个值有正有负,其实有现成的Sin函数可以让我们用
radian+=0.01f;
dy=Mathf.Sin(radian)*radius;

因此综合下来就是
else{
radian += perRadian;
float dy = Mathf.Sin(radian) * radius;
transform.position = originPos + new Vector3(0, dy, 0);
}

到这里基本功能都实现了,但是我们还是需要一个bool值来防止在上下震动的时候如果满足了if的条件就走了第一个if的路径,我们在if后面再加一个并且的条件
if (Vector3.Distance(transform.position, Target.transform.position) > 0.1f&& !isarrive)
然后我们在else里面加上 !isarrive=true;这样就不会走if的条件了。我们这样完成了一次靠近和震动

接下来我们需要让他回去if条件里,但在这之前我们观察一下我们之前的代码我们的上下震动用的弧度=0然后逐渐增大,但是我们下次再进来else的时候他就不说0开始了,所以我们要在飞行进入震动之前将radian设为0,但这个归0我们不能写在else里,因为update会执行打乱sin函数的连续性,因此我们要写在if里面,这样等待else走完一整个我们在if里面重新走的时候radian还是从0开始意味着sin的x也是从0开始。
接下来我们开始receed的代码,我们要写在else里面,因为我们是要在else里面判断当满足了一定的条件我们就从else里面跳出去转到if里面,那么我们的条件是什么呢?就是我们在Scene场景里把物体离生物远到一定距离了,这个时候我们就选择把变量isarrive=false,让它可以走if条件
因此综合:
public void Postpone()
{
if (Vector3.Distance(transform.position, Target.transform.position) > 0.3f && isarrive)
{
time += Time.deltaTime;
if (time > 0.5f)
{
isarrive = false;
}
}
}
但在这里我们还写了一个 if (time > 0.5f)是因为我们想让他在到达这个条件的时候不要马上回到if里,等待0.5秒之后再走if,一次我们要在if里面再写一个time=0;

整体的代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Rotate : MonoBehaviour
{

public float Speed = 1f;
public float fixangle = 2f;
public GameObject Target; //目标
private float time;
private float shakeTime;

public float radian = 0; // 弧度
public float perRadian = 0.01f; // 每次变化的弧度
public float radius = 0.1f; // 半径
Vector3 originPos; // 开始时候的坐标
bool isarrive;
bool isshake;
private void Start()
{

}
void Update()
{
    if (Vector3.Distance(transform.position, Target.transform.position) > 0.1f && !isarrive)
    {
        RotateAround();
        Go();
        if (isshake)
        {
            isshake = false;
        }
        time = 0;
        shakeTime = 0;
        radian = 0;
    }
    else
    {
        shakeTime += Time.deltaTime;
        isarrive = true;
        if (shakeTime > 0.2f)
        {
            InitialPos();
            Shake();
            Ajust();
        }
        Postpone();
    }
}

public void RotateAround()
{
    Vector3 relativePos = Target.transform.position - transform.position;
    var Toward = Quaternion.LookRotation(relativePos);
    var Lerp = fixangle / Vector3.Angle(transform.forward, relativePos);
    transform.rotation = Quaternion.Slerp(transform.rotation, Toward, Lerp > 1 ? 1 : Lerp);
}
public void Go()
{
    transform.position += transform.forward * Speed * Time.deltaTime;
}
public void Shake()
{
    radian += perRadian; // 弧度每次加0.03
    float dy = Mathf.Sin(radian) * radius; // dy定义的是针对y轴的变量
    transform.position = originPos + new Vector3(0, dy, 0);
}
public void Ajust()
{
    if (transform.rotation.x != 0)
    {
        Quaternion rotation = Quaternion.Euler(new Vector3(0, Random.Range(0, 360), 0));
        transform.rotation = Quaternion.Slerp(transform.rotation, rotation, 2f * Time.deltaTime);
    }
}
public void Postpone()
{
    if (Vector3.Distance(transform.position, Target.transform.position) > 0.3f && isarrive)
    {
        time += Time.deltaTime;
        if (time > 0.5f)
        {
            isarrive = false;
        }
    }
}
public void InitialPos()
{
    if (!isshake)
    {
        originPos = transform.position;
        isshake = true;
    }
}

}

猜你喜欢

转载自blog.csdn.net/vickieyy/article/details/88310355