unity2D/3D实现绕某点弧形运动、钟摆的往复运动、自动对准

1.2D实现两物体的自动对准效果

在捕鱼游戏中,玩家的手指点击屏幕,炮弹自动打向手指的方向是怎样实现的?
首先来想一下,如果我们想要自动追踪玩家手指的运动我们需要知道,手指按下的位置与炮弹的位置相差的角度,那么这个角度要怎样计算呢?
首先,我们尝试着把手指与炮管放在同一个坐标系中,如下图
在这里插入图片描述
所以我们现在要算出来的应该是那个坐标呢?其实不管是算角x0玩家(角1)或者角玩家0x(角2)也好,算出其中一个然后用90-这个角度就可以了,我们现在以角1来举例,,这个角的角度tan角度 = (敌人坐标Y-玩家坐标Y)/(敌人坐标x-玩家坐标x) ,这样球出来的是一个tan数值,所以我们需要把这个角度转换成我们熟知的度数,也就是 float angle = Mathf.Atan(tan角度),求出了选装的角度,就可以来设置物体自身欧拉角,由于我们要选装的事XY轴构成的平面,我们要以z轴为旋转轴来选装,使物体绕着自身的坐标系旋转求出的角度,这样敌人就可以根据玩家的位置自动瞄准了,代码如下

using UnityEngine;

using System.Collections;

public class enemy : MonoBehaviour {

//存储角度值。

private float angle;

//玩家位置。

public Transform m_player;

//申请一个变量存储gun游戏物体的prefab。

public Transform gun;

void Start () {

}

void Update () {

//计算角度

angle =Mathf.Rad2Deg*Mathf.Atan ((transform.position.y - m_player.position.y) / (transform.position.x - m_player.position.x));

//判断角度所在象限,并进行修正。

if (transform.position.x - m_player.position.x < 0)

angle=angle-90;

else 

angle=angle+90;

//设置物体的自身欧拉角,是物体绕自身坐标系在Z轴,旋转Z度。

transform.localEulerAngles=new Vector3(0,0,angle);

//生成gun物体。

Instantiate (gun, transform.position, transform.rotation);

}

}
2.实现钟摆的往复运动

方法一:使用unity自带的链节组件,进行相应的设置之后可以实现
这里要说的是第二种方法,也就是代码实现
在这里实际上是通过计算旋转轴、通过角速度旋转、然后通过transform.RotateAround来实现围绕某一个轴旋转角度的效果

using UnityEngine;
using System.Collections;
public class Pendulum : MonoBehaviour
{
    public Transform m_anchor;        //圆点
    public float g = 9.8f;            //重力加速度
    private Vector3 m_rotateAxis;    //旋转轴
    private float w = 0;                //角速度
    // Use this for initialization
    void Start()
    {
        //求出旋转轴
        m_rotateAxis = Vector3.Cross(transform.position - m_anchor.position, Vector3.down);
    }
    void DoPhysics()
    {
        float r = Vector3.Distance(m_anchor.position, transform.position);
        float l = Vector3.Distance(new Vector3(m_anchor.position.x, transform.position.y, m_anchor.position.z), transform.position);
        //当钟摆摆动到另外一侧时,l为负,则角加速度alpha为负。
        Vector3 axis = Vector3.Cross(transform.position - m_anchor.position, Vector3.down);
        if (Vector3.Dot(axis, m_rotateAxis) < 0)
        {
            l = -l;
        }
        float cosalpha = l / r;
        //求角加速度
        float alpha = (cosalpha * g) / r;
        //累计角速度
        w += alpha * Time.deltaTime;
        //求角位移(乘以180/PI 是为了将弧度转换为角度)
        float thelta = w * Time.deltaTime * 180.0f / Mathf.PI/2;
        //绕圆点m_ahchor的旋转轴m_rotateAxis旋转thelta角度
        transform.RotateAround(m_anchor.position, m_rotateAxis, thelta);
    }
    // Update is called once per frame
    void Update()
    {
        DoPhysics();
    }
}

第二种方法

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class moveText : MonoBehaviour
{
    public Transform cur;
   
    
    bool forward = false;
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        float angle = (cur.transform.position.y - this.transform.position.y) / (cur.transform.position.x - this.transform.position.x);
        angle = Mathf.Rad2Deg* Mathf.Atan(angle);

        move_back(move_dir(this.transform.position.x));
        move_forward(forward);


    }
    private bool move_dir(float pos)
    {
        if (pos < -12)
        {
            forward = true;
            Debug.Log(this.transform.position.x);
        }

        if (pos > 6)
        {
            forward = false;
        }
        return forward;
    }

    private void move_forward(bool fob)
    {
        if(!fob)
        {
            this.transform.RotateAround(cur.transform.position, Vector3.back,  10*Time.deltaTime);
        }
        return;
    }

    public void move_back(bool fob)
    {
        if(fob)
        {
            this.transform.RotateAround(cur.transform.position, Vector3.forward ,  10*Time.deltaTime);
        }
        return;
    }
}

弧形运动移动到指定地点
using UnityEngine;
using System.Collections;

public class MoveTest : MonoBehaviour
{
    public GameObject target;   //要到达的目标  
    public float speed = 10;    //速度  
    public int rotationAngle = 60;
    private float distanceToTarget;   //两者之间的距离  
    private bool move = true;
    public GameObject target2;

    void Start()
    {
        //计算两者之间的距离  
        distanceToTarget = Vector3.Distance(this.transform.position, target.transform.position);
        StartCoroutine(Move());
    }

    IEnumerator Move()
    {

        while (move)  //移动到目标点停止移动
        {
            Vector3 targetPos = target.transform.position;

            //让始终它朝着目标  
            this.transform.LookAt(targetPos);

            //计算弧线中的夹角  
            float angle = Mathf.Min(1, Vector3.Distance(this.transform.position, targetPos) / distanceToTarget) * rotationAngle;
            this.transform.rotation = this.transform.rotation * Quaternion.Euler(Mathf.Clamp(-angle, -42, 42), 0, 0);
            float currentDist = Vector3.Distance(this.transform.position, target.transform.position);
            if (currentDist < 0.5f)
                move = true;
            this.transform.Translate(Vector3.forward * Mathf.Min(speed * Time.deltaTime, currentDist));
            yield return null;
        }
        while(!move)
        {
            Vector3 targetPos = target2.transform.position;

            //让始终它朝着目标  
            this.transform.LookAt(targetPos);

            //计算弧线中的夹角  
            float angle = Mathf.Min(1, Vector3.Distance(this.transform.position, targetPos) / distanceToTarget) * rotationAngle;
            this.transform.rotation = this.transform.rotation * Quaternion.Euler(Mathf.Clamp(-angle, -42, 42), 0, 0);
            float currentDist = Vector3.Distance(this.transform.position, target.transform.position);
            if (currentDist < 0.5f)
                move = false;
            this.transform.Translate(Vector3.forward * Mathf.Min(speed * Time.deltaTime, currentDist));
            yield return null;
        }
    }


}
Unity2D/3D开发流程主要包括以下几个步骤: 1. 确定游戏类型和玩法:在开始开发前,需要确定游戏类型和玩法,包括游戏的主题、场景、角色、关卡、道具等,以及游戏的操作方式、规则、目标等。 2. 设计游戏关卡和场景:在确定游戏类型和玩法后,需要设计游戏的关卡和场景,包括地图、道具、障碍、敌人等。在设计时需要考虑游戏的难度、节奏、流畅度和趣味性等因素。 3. 创建游戏对象和元素:在设计游戏关卡和场景后,需要创建游戏对象和元素,包括角色、道具、敌人、场景元素等。可以使用Unity的编辑器来创建和编辑游戏对象和元素,也可以使用第三方工具来创建和导入。 4. 添加组件和脚本:在创建游戏对象和元素后,需要添加相应的组件和脚本来控制其行为和动作。可以使用Unity的组件和脚本来实现常见的游戏行为,也可以使用C#脚本来编写自定义的游戏逻辑。 5. 调试和测试:在添加组件和脚本后,需要进行调试和测试,以确保游戏的功能和表现符合设计要求。可以使用Unity的调试工具来检查游戏对象和脚本的状态和行为,也可以使用第三方工具来进行测试和调试。 6. 优化和打包发布:在完成测试和调试后,需要对游戏进行优化和打包发布。可以使用Unity的优化工具来优化游戏性能和资源占用,也可以使用Unity的打包工具来打包和发布游戏到不同的平台和设备。 以上是Unity2D/3D开发流程的主要步骤,每个步骤都需要认真考虑和实践,以确保游戏的质量和用户体验。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值