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;
}
}
}