Unity3D 2D游戏开发 官方教程。(七)

七移动脚本
7.1创建脚本
创建移动脚本MovingObject.cs控制对象的移动,此类为Player以及Enemy移动控制的几类。
7.2 修改脚本

using UnityEngine;
using System.Collections;
public abstract class MovingObject : MonoBehaviour 
{
    //对象移动所需时间
    public float moveTime = 0.1f;
    //碰撞层,所有需要检测碰撞的对象都在此层中
    public LayerMask blockingLayer;
    //碰撞检测
    private BoxCollider2D boxCollider;
    //钢体组件
    private Rigidbody2D rb2D;
    //高效计算使用
    private float inverseMoveTime;

    protected virtual void Start () 
    {
        //获取当前对象的组件信息
        boxCollider = GetComponent<BoxCollider2D>();
        rb2D = GetComponent<Rigidbody2D>();
        //乘法比除法效率高
        inverseMoveTime = 1f/ moveTime;
    }
    //移动并检测碰撞
    protected bool Move(int xDir,int yDir,out RaycastHit2D hit)
    {
        Vector2 start = transform.position;
        Vector2 end = start + new Vector2(xDir,yDir);
        //停止自身碰撞器,防止射线碰撞到自己的碰撞器
        boxCollider.enabled = false;
        //发射射线从start到end,并检测BlockingLayer中的碰撞情况。如果有碰撞返回到hit中
        hit = Physics2D.Linecast(start,end,blockingLayer);
        boxCollider.enabled = true;
        if(hit.transform == null)
        {
            //hit为空,表示没有碰撞对象,即可以移动
            StartCoroutine(SmoothMovement(end));
            return true;
        }
        return false;
    }
    //T为要检测的目标碰撞对象类型wall,food,enemy,exit等
    protected virtual void AttemptMove<T>(int xDir,int yDir)
        where T : Component
    {
        RaycastHit2D hit;
        bool canMove = Move (xDir,yDir,out hit);
        if(hit.transform == null)
            return;
        T hitComponent = hit.transform.GetComponent<T>();
        if(!canMove && hitComponent != null)
            OnCantMove(hitComponent);
    }
    //对象平滑移动
    protected IEnumerator SmoothMovement(Vector3 end)
    {
        //计算到end点距离
        float sqrRemainingDistance = (transform.position - end).sqrMagnitude;
        //平滑移动(float.Epsilon无线接近0)
        while(sqrRemainingDistance > float.Epsilon)
        {
            Vector3 newPosition = Vector3.MoveTowards(rb2D.position , end,inverseMoveTime * Time.deltaTime);
            rb2D.MovePosition(newPosition);
            sqrRemainingDistance = (transform.position - end).sqrMagnitude;
            yield return null;
        }
    }
    //路线上有碰撞对象不能移动的时候,需要发生的控制
    protected abstract void OnCantMove<T>(T component)
        where T : Component;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值