2d角色跳跃 unity3d
2017-02-13 14:30:00 weixin_33767813 阅读数 55
using UnityEngine;
using System.Collections;

public class HeroColtrol : MonoBehaviour
{
    private Rigidbody2D HeroRd;
    public float MoveSpeed;
    public float JumpHeight;
    void Awake()
    {
        HeroRd = transform.GetComponent<Rigidbody2D>();
    }


    void FixedUpdate()
    {
        float h = Input.GetAxis("Horizontal");
        if (!h.Equals(0))
        {
            HeroRd.velocity = new Vector2(h * MoveSpeed, HeroRd.velocity.y);
        }
        if (Input.GetKeyDown(KeyCode.Space))
        {
            if (HeroRd.velocity.y.Equals(0))
                HeroRd.velocity = new Vector2(HeroRd.velocity.x, JumpHeight);
        }

    }

}

img_b31e84f622515094669153d0387f082d.png
图片.png
2017-02-13 14:30:00 weixin_34239169 阅读数 330
using UnityEngine;
using System.Collections;

public class HeroColtrol : MonoBehaviour
{
    private Rigidbody2D HeroRd;
    public float MoveSpeed;
    public float JumpHeight;
    void Awake()
    {
        HeroRd = transform.GetComponent<Rigidbody2D>();
    }


    void FixedUpdate()
    {
        float h = Input.GetAxis("Horizontal");
        if (!h.Equals(0))
        {
            HeroRd.velocity = new Vector2(h * MoveSpeed, HeroRd.velocity.y);
        }
        if (Input.GetKeyDown(KeyCode.Space))
        {
            if (HeroRd.velocity.y.Equals(0))
                HeroRd.velocity = new Vector2(HeroRd.velocity.x, JumpHeight);
        }

    }

}

2020966-6b3d3a8ceb6c3d20.png
图片.png
2018-07-27 18:18:52 u013628121 阅读数 1965
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class SpaceJump : MonoBehaviour
{

    public float distance = 5f;
    public float hight = 3f;
    public float useTime = 1.5f;

    public float rigidbodyForce = 7f;


    Vector3 addForce;


    /// <summary>
    /// 跳跃结束 落地,其他地方调用 ,(跳跃中 && 落入地面碰撞器)调用 
    /// </summary>
    public void JumpOver()
    {
        addForce = Vector3.zero;
        GetComponent<Rigidbody>().velocity = Vector3.zero;
    }

    // Use this for initialization
    void iTweenJump()
    {

        Vector3 p2;//角色落点
        Vector3 p1;//最高点

        Vector3 dir = GetToMouseDir();//方向是跳向鼠标,transform.forward是跳向前方


        p1 = transform.position + dir * (distance / 2) + transform.up * hight;//第二个点:起始位置前方几米处上方几米的坐标.

        p2 = transform.position + dir * distance;
        //找到碰撞器 落脚点
        RaycastHit raycastHit; //碰撞体信息
        if (Physics.Raycast(p2, Vector3.down, out raycastHit, 81f))
        {
            //raycastHit.point 碰撞到的点
            //碰撞到的物体  raycastHit.transform.gameObject
            p2 = raycastHit.point;

        }

        Vector3[] paths = new Vector3[3];
        paths[0] = transform.position;
        paths[1] = p1;
        paths[2] = p2;
        iTween.MoveTo(gameObject, iTween.Hash("path", paths, "movetopath", true, "time", useTime));//movetopath=false按点移动,=true按照点构成的曲线路径移动
    }


    /// <summary>
    ///角色坐标 到 鼠标位置的方向
    /// </summary>
    Vector3 GetToMouseDir()
    {
        Vector3 dir = Vector3.forward;
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit = new RaycastHit();
        if (Physics.Raycast(ray, out hit))
        {
            Vector3 hitPos = hit.point;
            Vector3 playerPos = transform.position;
            //向量减法 和y无关,所以同步一下高度
            playerPos.y = hitPos.y;
            //向量减法,得到一个向量,包含方向和距离
            dir = (hitPos - playerPos);
            //归一化 去除距离 ,只要方向,如果不去除距离 ,那么角色闪到鼠标点击的位置
            dir = dir.normalized;
        }
        return dir;
    }

    void RigidbodyJump()
    {
        Rigidbody rigidbody = GetComponent<Rigidbody>();

        //打开刚体移动
        rigidbody.constraints = RigidbodyConstraints.None;
        rigidbody.constraints = RigidbodyConstraints.FreezeRotation;

        Vector3 dir = GetToMouseDir();

        //角色当前刚体速度
        float xSpeed = 0;
        float zSpeed = 0;
        if (GetComponent<NavMeshAgent>() == null || GetComponent<NavMeshAgent>().enabled ==false)
        {
             xSpeed = rigidbody.velocity.x;
             zSpeed = rigidbody.velocity.z;

        }
        else
        {
            xSpeed = GetComponent<NavMeshAgent>().velocity.x;
            zSpeed = GetComponent<NavMeshAgent>().velocity.z;
        }

        Vector3 add;

        if (xSpeed== 0 && zSpeed== 0)
        {//站立状态:向上眺
            add = transform.up * hight;
            rigidbody.velocity += add;
        }
        else
        {//移动状态:向鼠标方向跳
            add = dir * distance + transform.up * hight;
            
            if (addForce ==Vector3.zero)
            {//判断是第一次跳跃,就跳固定值高度
                rigidbody.velocity = add;
            }
            else
            {
                rigidbody.velocity += add;
            }
        }

        addForce += add;
        //Debug.LogError("Rigidbody" + GetComponent<Rigidbody>().velocity+"zSpeed:" + zSpeed+ "xSpeed:"+ xSpeed+"dir:" + dir+"add"  + add+"rigidbody.velocity = " +rigidbody.velocity + "force" + addForce);
        rigidbody.AddForce(addForce);

        // 设置 角色状态  动画 等为跳跃
    }

    public void Jump()
    {
            if (GetComponent<Rigidbody>() == null)
            {
                iTweenJump();
            }
            else
            {
                RigidbodyJump();
            }
     }
    

}

 

2018-07-19 10:56:00 weixin_34186931 阅读数 6

如果角色运动过快会导致嵌入地面再反弹出来 :
429727-20180719105320295-863459381.png

可以使用更高质量的检测方式 "Continuous" :就可以解决这个问题
429727-20180719105410255-1096318059.png

转载于:https://www.cnblogs.com/night-ride-depart/p/9334548.html

2017-06-19 10:42:21 yongh701 阅读数 1913

《【Unity3D】自动寻路》(点击打开链接)万般好,但锁死Y轴这点导致非常蛋疼的一个问题,我需要在自动寻路的过程允许游戏主角进行跳跃。毕竟玩家都说了,在3D游戏里面不让主角跳跃是一个很严重的问题,就像《阿玛拉王国》本来做得非常好,但就是不能跳,导致大打折扣。那么如果在Unity3D自动寻路的过程中进行跳跃呢?下面举一个例子说明这个问题:


如图所示,假设图中的小球就是我们的主角,我按左键可以让它自动寻路,按右键可以让它跳,同时到了边界还不会出现一堵无形的墙,小球能自然滑落的。

具体制作过程如下所示:

1、一如《【Unity3D】自动寻路》(点击打开链接)拖Plane,整些Cube作障碍体,Sphere做主角,同时设置一个光源,并给这些东西加上材质。然后保存场景,将Plane和Cube设置为Navigation Static,小球加上Nav Mesh Agent和Rigidbody,完成自动寻路的烘培。


2、给小球赋予GameScript.cs如下所示,则完成:

using UnityEngine;
using System.Collections;

public class GameScript : MonoBehaviour
{
    private NavMeshAgent navMeshAgent;
    private bool is_jumping, out_of_bound;//用于设置小球是否跳跃和已经到达自动寻路边缘的flag

    void Start()
    {
        navMeshAgent = gameObject.GetComponent<NavMeshAgent>();//初始化navMeshAgent  
        is_jumping = false;
        out_of_bound = false;
    }

    void Update()
    {
        if (Input.GetMouseButtonDown(0) && !is_jumping && !out_of_bound)
        {//如果不是在跳跃、不是到达自动寻路边缘,按下鼠标左键   
            //自动寻路
            Ray mRay = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit mHit;
            if (Physics.Raycast(mRay, out mHit))
            {
                if (mHit.collider.gameObject.name == "Plane")//如果点的是Plane上的一点
                {
                    this.rigidbody.velocity = new Vector3(0, 0, 0);//这里是考虑到跳跃落地之后,用户马上要自动寻路的情况
                    navMeshAgent.SetDestination(mHit.point);
                }
            }
        }

        if (Input.GetMouseButtonDown(1) && !is_jumping && !out_of_bound)//按下鼠标右键的话
        {
            Ray mRay = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit mHit;
            if (Physics.Raycast(mRay, out mHit))
            {
                if (mHit.collider.gameObject.name == "Plane")
                {
                    navMeshAgent.enabled = false;//取消自动寻路
                    is_jumping = true;//让小球进行跳跃
                    this.rigidbody.velocity = new Vector3(0, 0, 0);
                    this.rigidbody.velocity = mHit.point + new Vector3(0, 5, 0);//基于一个点击位置方向加上y=5的向量速度
                }
            }

        }
        if ((this.transform.position.x > 4.6 && this.rigidbody.velocity.x > 0.01) ||
            (this.transform.position.x < -4.6 && this.rigidbody.velocity.x < -0.01) ||
            (this.transform.position.z > 4.6 && this.rigidbody.velocity.z > 0.01) ||
            (this.transform.position.z < -4.6 && this.rigidbody.velocity.z < -0.01))
        {//如果已经到了Plane的边缘
            out_of_bound = true;
            navMeshAgent.enabled = false;//关闭自动寻路
        }

        if (this.transform.position.y < -3)//如果小球已经掉得太下方
        {
            Application.LoadLevel("Navmesh_jump");//重新开始
        }
    }

    //小球如果和Plane开始碰撞
    void OnCollisionEnter(Collision collision)
    {
        if (collision.collider.gameObject.name == "Plane" && is_jumping)
        {
            is_jumping = false;
            navMeshAgent.enabled = true;//重新打开自动寻路
        }
    }

}
这里的难点就是因为自动寻路Nav Mesh Agent锁死了Y轴,导致和刚体Rigidbody想在3D世界中自由进行物理运动产生冲突,那么我们在小球需要跳跃的时候就不要这个自动寻路好了,同时自动寻路Nav Mesh Agent一旦小球到达了Plane的边界也会不知道为何会自动产生一股无形的墙,非要小球不能滑落,这里也和刚体Rigidbody产生冲突的,我们也是需要解除自动寻路Nav Mesh Agent,让小球得以滑落。

综上所述,其实来来去去是如果协调好自动寻路Nav Mesh Agent在何时开关的问题。这里在设置两个flag之后,在用户点击右键则让小球进行跳跃状态,执行《【Unity3D】用鼠标点击事件、AddForce完成跳跃与二段跳》(点击打开链接)对跳跃的处理,然后用到《【Unity3D】利用物体碰撞检测、键盘输入处理完成平衡球游戏》(点击打开链接)对碰撞检查的内容,设置进行跳跃状态的小球一旦与Plane碰撞,则重新回到自动寻路的状态。

Unity3d 人物的跳跃

阅读数 1582

Unity3d实现人物跳跃

阅读数 18484

Unity3D关于蓄力跳跃

阅读数 10105

没有更多推荐了,返回首页