2d游戏跳跃 unity3d

2017-02-13 14:30:00 weixin_33767813 阅读数 735
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-04-16 15:09:41 mian199614 阅读数 25766

首先给对象添加刚体和碰撞体。

在FixedUpdate中写入如下代码,不能是Update,因为是物理属性,必须要FixedUpdate

GetComponent<Rigidbody>().velocity += new Vector3(0, 5, 0); //添加加速度
GetComponent<Rigidbody>().AddForce(Vector3.up * mJumpSpeed); //给刚体一个向上的力,力的大小为Vector3.up*mJumpSpeed

完整代码如下



        transform.rotation = Quaternion.LookRotation(Vector3.forward, Vector3.up);
         if (Input.GetButtonDown("Jump"))
        {
            if (ground == true)
            {   


                //transform.Translate(new Vector3(Input.GetAxis("Horizontal")*distance, 2, Input.GetAxis("Vertical")*distance));
                GetComponent<Rigidbody>().velocity += new Vector3(0, 5, 0);
                GetComponent<Rigidbody>().AddForce(Vector3.up * mJumpSpeed);
                ground = false;
                Debug.Log("I am Pressing Jump");
            }
        }

ground用来判断你是在空中还是地面,如果是在空中,当然不能再让你跳。

另外如果要取消反冲力,在start方法里加GetComponent<Rigidbody>().freezeRotation = true;

2020-03-09 20:29:57 weixin_42554621 阅读数 1492

Unity 角色移动及动画调用

(1)首先要给 Sprite【游戏角色添加 刚体(Rigidbody2D)和碰撞体(Circle Colloder2D)】

(2)设置好角色的动画以及角色动画控制器里面的参数,这里使用了float 和bool 类型的参数 ,行走的动画调用的是float 类型,待机跳跃下降用的是bool
在这里插入速度述在这里插入图片描述(3)编写代码

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

public class player_move : MonoBehaviour
{
    
    private Rigidbody2D player_move_rd;//获得组件rigibody
    private Animator ani_player; //获得角色组件animator
    //可以直接public  
    



    public float speed;
    public float jumpforce;
    public Collider2D collider_player;//获得角色组件collider
    public LayerMask ground;//判断角色是不是在地面上如果不是就下降
   
    void Start()
    {
        player_move_rd = GetComponent<Rigidbody2D>();
        ani_player = GetComponent<Animator>();

        
    }

    void FixedUpdate()
    {


        
        //游戏角色的移动 调用函数
        Playermove();
        //跳跃 移动状态切换
        SwitchAnim();
    }

    void Playermove() {
        
        //人物移动
        float player_horizontalmove = Input.GetAxis("Horizontal");

        //人物面向问题   raw(-1,1)
        float facedircetion = Input.GetAxisRaw("Horizontal");

       

        //人物移动函数
        if (player_horizontalmove !=0 )
        {
            player_move_rd.velocity = new Vector2(player_horizontalmove * speed*Time.deltaTime, player_move_rd.velocity.y);
            ani_player.SetFloat("running", Mathf.Abs(facedircetion));
            Debug.Log("你正在移动.");
        }
        if(facedircetion != 0)
        {
            transform.localScale = new Vector3(facedircetion, 1, 1);


        }
        //人物跳跃函数
        if (Input.GetButtonDown("Jump"))
        {

            player_move_rd.velocity = new Vector2(player_move_rd.velocity.x, jumpforce * Time.deltaTime);
            ani_player.SetBool("jumping", true);
            Debug.Log("你正在跳跃.");

        }


    }

    
    //跳跃 移动状态切换
    void SwitchAnim()
    {
        ani_player.SetBool("idel", false);

        if (ani_player.GetBool("jumping"))
        {
            if (player_move_rd.velocity.y < 0)
            {
                ani_player.SetBool("jumping", false);
                ani_player.SetBool("falling", true);
                Debug.Log("你正在升天.");
            }

        }
        else if(collider_player.IsTouchingLayers(ground))
        {
            ani_player.SetBool("falling",false);
            ani_player.SetBool("idel",true);

            Debug.Log("你正在下降.");


        }
    }



}

大概思路就是这样,如果有什么问题可以留言

2020-03-18 22:46:15 pointeryang 阅读数 240

大家好,很高兴和大家分享我们的Unity游戏开发经验, 这是我们的系列视频的第三期视频, 在这期视频中,我们将在Unity中使用C#脚本来实现角色的跳跃,包括跳跃代码的改进,让角色跳跃更加真实,同时也为后面的游戏开发做准备。 不管您是否有Unity的使用和开发经验, 都希望这段视频对您有帮助。

Unity2D游戏开发基础(三)控制角色——跳跃

2017-10-12 23:45:25 q764424567 阅读数 6271

一、前言

最近跑酷游戏比较流行,开发教程也很多,但是大部分都是不太详细,这篇文章就带着大家一步一步开发出来一个跑酷类的游戏,教程比较基础,适合大部分Unity开发的初学者。
还有就是,此专栏已经开通收费,里面整合的都是小游戏的开发教程,想要学习Unity开发游戏的,都可以订阅一下。
如果文章出现什么问题,就及时联系我

二、效果图&下载链接

在这里插入图片描述
Github地址:https://github.com/764424567/Game_Parkour

三、教程

在教程开始之前,我们分析一下跑酷类游戏制作思路。
首先是道路和障碍物,我们可以先设置三段道路,然后障碍物随机生成
道路中间有抵达点,角色到达抵达点判断是否将后面的道路移动到前面接起来。
首先到达第一段的抵达点,肯定是不切换
到达第二段的抵达点,将1号路段移动到最前面
到达第三段的抵达点,将2号路段移动到最前面
循环往复,无穷尽也
然后是主角的移动脚本,躲避障碍物,移动位置固定三个点,可以跳,可以铲地
主角碰到障碍物就挂,游戏结束

1、新建项目

博主的Unity版本是Unity5.6.1f1,推荐大家使用我这个版本,或者其他的5.6.x版本,不然可能会出现各种各样奇奇怪怪的问题。
在这里插入图片描述
文件目录的话就按照我这个目录来,比较清晰明了。

2、导入资源

资源已经上传到Github,需要的可以下载
https://github.com/764424567/Unity-plugin/tree/master/ParkourDemo
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3、处理动画资源

在这里插入图片描述
可以看到所有的动画文件都有。
接着我们就可以新建一个Animator Controller文件来管理动画文件。
在这里插入图片描述
命名随意。
在这里插入图片描述
接着我们将动画剪辑拖到Animator处理面板中:
在这里插入图片描述
默认状态是run,然后有jump 、slide、idle
在这里插入图片描述
接着就是“Take Transition”将run和jump 以及 run 、slide、idle连下线。

设置两个bool值,来控制动画的切换:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
接下来我们就可以在场景中看一下动画效果了:
在这里插入图片描述

4、处理路段模型

在这里插入图片描述
首先我们找到导入的资源SimpleRoadwork,里面有一个Demo场景,点进去可以看一下各类模型:
在这里插入图片描述
在Prefabs文件夹中,可以找到我们需要的各类模型,包括路面、路标、障碍物:
在这里插入图片描述
接下来,我们就设计一下路面:
在这里插入图片描述
在这里插入图片描述
接着摆放路标:
在这里插入图片描述
接着摆放障碍物:
在这里插入图片描述
因为障碍物我们要后期自动生成,现在就可以先隐藏起来。
在这里插入图片描述
然后设置到达点(到达点的目的是当角色到达这个位置的时候,自动切换路线):
在这里插入图片描述
隐藏它的Mesh Renderer ,将BoxCollider IsTrigger设置成true:
在这里插入图片描述
路段就完成了:

在这里插入图片描述
整个目录如下:
在这里插入图片描述
不会摆放也没有关系,我已经设置好了,用我的也行。

5、主角模型处理

在这里插入图片描述

明显是有点大,我们给它同比例缩小一下:
在这里插入图片描述
在这里插入图片描述
接着设置一下摄像机的视角:

在这里插入图片描述
在这里插入图片描述

6、生成障碍物

新建脚本Control_Scenes.cs
我们首先来生成障碍物:

using UnityEngine;

public class Control_Scenes : MonoBehaviour
{
    public GameObject[] m_ObstacleArray;
    public Transform[] m_ObstaclePosArray;

    void Start()
    {
        Spawn_Obstacle(1);
    }
	
	//生成障碍物
	public void Spawn_Obstacle(int index)
    {
        //销毁原来的对象
        GameObject[] obsPast = GameObject.FindGameObjectsWithTag("Obstacle" + index);
        for (int i = 0; i < obsPast.Length; i++)
        {
            Destroy(obsPast[i]);
        }
        //生成障碍物
        foreach (Transform item in m_ObstaclePosArray[index])
        {
            GameObject prefab = m_ObstacleArray[Random.Range(0, m_ObstacleArray.Length)];
            Vector3 eulerAngle = new Vector3(0, Random.Range(0, 360), 0);
            GameObject obj = Instantiate(prefab, item.position, Quaternion.Euler(eulerAngle));
            obj.tag = "Obstacle" + index;
        }
    }
}

将脚本挂在Control_Scenes对象上:
将Prefab文件夹里面的模型拖入到ObstacleArray对象数组卡槽中
将隐藏以后的障碍物拖入到ObstaclePosArray对象数组卡槽中
在这里插入图片描述
添加Tag:
在这里插入图片描述
运行看一下:
在这里插入图片描述

7、路段切换

我们接着打开Control_Scenes.cs
添加函数:

void Start()
{
        //Spawn_Obstacle(1);
        Change_Road(1);
}
public void Change_Road(int index)
{
        if (m_ISFirst && index == 0)
        {
            m_ISFirst = false;
            return;
        }
        else
        {
            int lastIndex = index - 1;
            if (lastIndex < 0)
                lastIndex = 2;
            m_RoadArray[lastIndex].transform.position = m_RoadArray[lastIndex].transform.position - new Vector3(150, 0, 0);
            Spawn_Obstacle(lastIndex);
        }
}

PS:这里解释一下代码,怎么切换的呢
举个例子,角色跑到了第二段,那么第一段要移动到第三段后面隔一个路段长度的距离,接下来画个图:
在这里插入图片描述
那么为啥x轴减去150。这是因为我发现这三条路段的距离都差了50,坐标轴是负轴,所以就减去了150。
在这里插入图片描述

我们可以测试一下效果:
在这里插入图片描述
但是仅仅这样是不够的,我们还需要在角色到达抵达点的时候,切换路线,当然第一段路不用切换,因为再切就没了。。
这个在我们写完角色移动以后再补充。

8、角色移动

新建脚本:Control_Player.cs
说明一下:因为我们设定的三条道,所以角色只能在三条道里面切换。那么只需要改变角色的z值就可以了。如果角色在最左边,那么只能往右移动,同理在最右边,只能往左移动,在中间两边都可以移动。

接着我们就可以看一下z轴的值:
中间:
在这里插入图片描述
在这里插入图片描述

左边:
在这里插入图片描述
在这里插入图片描述
右边:
在这里插入图片描述
在这里插入图片描述
代码:

using UnityEngine;

public class Control_Player : MonoBehaviour
{
    //前进速度
    public float m_ForwardSpeeed = 7.0f;
    //动画组件
    private Animator m_Anim;
    //动画现在状态
    private AnimatorStateInfo m_CurrentBaseState;

    //动画状态参照
    static int m_jumpState = Animator.StringToHash("Base Layer.jump");
    static int m_slideState = Animator.StringToHash("Base Layer.slide");

    // Use this for initialization
    void Start()
    {
        m_Anim = GetComponent<Animator>();
    }

    // Update is called once per frame
    void Update()
    {
        transform.position += Vector3.left * m_ForwardSpeeed * Time.deltaTime;
        m_CurrentBaseState = m_Anim.GetCurrentAnimatorStateInfo(0);
        if (Input.GetKeyDown(KeyCode.W))
        {
            m_Anim.SetBool("jump", true);
        }
        else if (Input.GetKeyDown(KeyCode.S))
        {
            m_Anim.SetBool("slide", true);
        }
        else if (Input.GetKeyDown(KeyCode.A))
        {
            Change_PlayerZ(true);
        }
        else if (Input.GetKeyDown(KeyCode.D))
        {
            Change_PlayerZ(false);
        }
        if (m_CurrentBaseState.fullPathHash == m_jumpState)
        {
            m_Anim.SetBool("jump", false);
        }
        else if (m_CurrentBaseState.fullPathHash == m_slideState)
        {
            m_Anim.SetBool("slide", false);
        }
    }

    public void Change_PlayerZ(bool IsAD)
    {
        if (IsAD)
        {
            if (transform.position.z == -14.7f)
                return;
            else if (transform.position.z == -9.69f)
            {
                transform.position = new Vector3(transform.position.x, transform.position.y, -14.7f);
            }
            else
            {
                transform.position = new Vector3(transform.position.x, transform.position.y, -9.69f);
            }
        }
        else
        {
            if (transform.position.z == -6.2f)
                return;
            else if (transform.position.z == -9.69f)
            {
                transform.position = new Vector3(transform.position.x, transform.position.y, -6.2f);
            }
            else
            {
                transform.position = new Vector3(transform.position.x, transform.position.y, -9.69f);
            }

        }
    }
}

键盘WSAD控制上跳,下滑,左右移动等操作。现在就可以去试试啦。
在这里插入图片描述

但是,有一点哈,角色怎么越跑越远离开了我们呢,因为,还没有写摄像机跟随脚本,接下来继续吧。

9、摄像机跟随

新建脚本Control_Camera.cs

using UnityEngine;

public class Control_Camera : MonoBehaviour
{
	//间隔距离
	public float m_DistanceAway = 5f;
	//间隔高度
	public float m_DistanceHeight = 10f;
	//平滑值
	public float smooth = 2f;               
	//目标点
	private Vector3 m_TargetPosition;      
	//参照点
	Transform m_Follow;        

	void Start()
	{
		m_Follow = GameObject.Find("Player").transform;
	}

	void LateUpdate()
	{
		m_TargetPosition = m_Follow.position + Vector3.up * m_DistanceHeight - m_Follow.forward * m_DistanceAway;
		transform.position = Vector3.Lerp(transform.position, m_TargetPosition, Time.deltaTime * smooth);
	}
}

OK 摄像机跟着Player跑起来了

10、碰撞检测

我们需要不停的躲避障碍物,一旦碰撞到障碍物就dead了
我们首先修改障碍物的碰撞器属性:
在这里插入图片描述
Mesh Collider : Is Trigger=true
在这里插入图片描述
我们给Player加上刚体和碰撞体:
在这里插入图片描述
注意要勾上Is Trigger

打开Control_Player.cs脚本:

//游戏结束
bool m_IsEnd = false;
void OnGUI()
{
        if (m_IsEnd)
        {
            GUIStyle style = new GUIStyle();
            style.alignment = TextAnchor.MiddleCenter;
            style.fontSize = 40;
            style.normal.textColor = Color.red;
            GUI.Label(new Rect(Screen.width / 2 - 100, Screen.height / 2 - 50, 200, 100), "你输了~", style);
        }
}
void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.name == "Vehicle_DumpTruck" || other.gameObject.name == "Vehicle_MixerTruck")
        {
            m_IsEnd = true;
            m_ForwardSpeeed = 0;
            m_Anim.SetBool("idle", true);
        }
    }

11、切换道路

在第七章的时候就已经写好了道路切换,但是一直没有讲到碰撞检测,那么现在我们就结合碰撞检测,检测到抵达点然后切换道路吧

我们首先找到三个抵达点:MonitorPos
然后改名叫做MonitorPos0 MonitorPos1 MonitorPos2
在这里插入图片描述
修改一下BoxCollider的Is Trigger属性:
在这里插入图片描述
修改Control_Player.cs的代码:

 //场景控制对象
Control_Scenes m_ControlScenes;
void Start()
{
        m_Anim = GetComponent<Animator>();
        m_ControlScenes = GameObject.Find("Control_Scenes").GetComponent<Control_Scenes>();
}
void OnTriggerEnter(Collider other)
{
        if (other.gameObject.name == "Vehicle_DumpTruck" || other.gameObject.name == "Vehicle_MixerTruck")
        {
            m_IsEnd = true;
            m_ForwardSpeeed = 0;
            m_Anim.SetBool("idle", true);
        }
        if (other.gameObject.name == "MonitorPos0")
        {
            m_ControlScenes.Change_Road(0);
        }
        else if (other.gameObject.name == "MonitorPos1")
        {
            m_ControlScenes.Change_Road(1);
        }
        else if (other.gameObject.name == "MonitorPos2")
        {
            m_ControlScenes.Change_Road(2);
        }
}