wei-unity

untiy

https://assetstore.unity.com/packages/essentials/asset-packs/2d-beginner-tutorial-resources-140167

移动对象:

Assets/Scripts/PlayerController.cs

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

public class PlayerController : MonoBehaviour
{
    public float speed = 5f;
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        //transform.Translate(transform.right * speed * Time.deltaTime);
        float moveX = Input.GetAxisRaw("Horizontal");
        float moveY = Input.GetAxisRaw("Vertical");
        Vector2 position = transform.position;
        position.x += moveX * speed * Time.deltaTime;
        position.y += moveY * speed * Time.deltaTime;
        transform.position = position;
    }
}

Tile瓦片部署场景

# 切割图片
Sprite Mode : Multiple
Sprite Editor
Pixels Per Unit : 64*3
# 自己的调色板
/Windows/2D/Tile Palette
# 部署场景

丰富场景

# 层级
Order in Layer  :  -1
# 克隆预制体
/Assets/Prefabs : 拖入目录存,拖出克隆
# 缸体
Rigidbody 2D 
Gravity Scale : 0 重力
# 碰撞
Box Collider 2D
Edit Collider :   腰部以下,碰撞
# Y轴排序
Edit -- Project Settings -- Graphics 
Coustom Axis  : x0 y1 z0
# z轴禁用旋转
Ruby对象/Rigidbody 2D/Constraints/Freeze Rotation :把z勾上
# 创建空目录容纳对象
backGround -- 将物体托入目录

处理抖动

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

public class PlayerController : MonoBehaviour
{
    public float speed = 5f;
    Rigidbody2D rbody; //刚体组件
    // Start is called before the first frame update
    void Start()
    {
        rbody = GetComponent<Rigidbody2D>();
    }
    // Update is called once per frame
    void Update()
    {
        //transform.Translate(transform.right * speed * Time.deltaTime);
        float moveX = Input.GetAxisRaw("Horizontal");
        float moveY = Input.GetAxisRaw("Vertical");
        Vector2 position = rbody.position;
        position.x += moveX * speed * Time.deltaTime;
        position.y += moveY * speed * Time.deltaTime;
        rbody.MovePosition(position);
    }
}

相机跟随

Windows -- Packge Manger -- All -- Cinemachine -- install

Cinemachine -- Create 2D Camera

CM vcam1 -- Follow : 角色对象

#窗口大小
CM vcam1 -- Lens -- Orthographic Sixe  : 5

水面禁行

Tilemap -- Add Component -- Tilemap Collider 2D 
Tiles -- 选中除了水面以外的所有瓦片 -- Collider Type : None
Tilemap -- Add Component -- Composite Collider 2D 
Tilemap -- Rigidbody 2D -- Gravity Scale : 0 去掉瓦片的重力
Tilemap -- Tilemap Collider 2D -- Used By Composite : 勾选合并
Tilemap -- Rigidbody 2D -- Body Type : static  钢体设置为静态不受物理作用

地图范围(相机边界)

CM vanm1 -- Add Extension : Cinemachine Confiner 选择添加相机控制

右键 -- Create Empty : 起名 CinemachineConfiner  添加空对象

CinemachineConfiner -- Add Component -- Polygon Collider 2D (可编辑的碰撞体,4个点)  给空对象加入4个点的碰撞体

CM vanm1 -- Bounding Shape 2D : 拖动CinemachineConfiner到此  边界形状绑定空碰撞体对象

CinemachineConfiner -- Polygon Collider 2D -- Is Trigger : 勾选只是触发。  不然相机把人物挤出去了。

草莓加血

草莓挂载: Collectible.cs 英汉:收藏

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 草莓拾取
/// </summary>
public class Collectible : MonoBehaviour
{
    /// <summary>
    /// 碰撞检测相关
    /// </summary>
    /// <param name="other"></param>
    void OnTriggerEnter2D(Collider2D other)
    {
        PlayerController pc = other.GetComponent<PlayerController>();
        if (pc != null)
        {
            if (pc.MyCurrentHealth < pc.MyMaxHealth) {
                pc.ChangeHealth(1);
                Destroy(this.gameObject);
            }
            //Debug.Log("玩家碰到了草莓!");
        }
    }
}

玩家挂载: PlayerController.cs 英汉:玩家控制

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

public class PlayerController : MonoBehaviour
{
    public float speed = 5f; //移动速度
    private int maxHealth = 5; //最大生命值
    private int currentHealth; //当前生命值
    public int MyMaxHealth { get { return maxHealth; } }
    public int MyCurrentHealth { get { return currentHealth; } }

    Rigidbody2D rbody; //刚体组件
    // Start is called before the first frame update
    void Start()
    {
        currentHealth = 2;
        rbody = GetComponent<Rigidbody2D>();
    }
    // Update is called once per frame
    void Update()
    {
        //transform.Translate(transform.right * speed * Time.deltaTime);
        float moveX = Input.GetAxisRaw("Horizontal");
        float moveY = Input.GetAxisRaw("Vertical");
        Vector2 position = rbody.position;
        position.x += moveX * speed * Time.deltaTime;
        position.y += moveY * speed * Time.deltaTime;
        rbody.MovePosition(position);
    }
    
   /// <summary>
   /// 改变玩家的生命值
   /// </summary>
   /// <param name="amount"></param>
    public void ChangeHealth(int amount)
    {
        //把玩家生命值约束在0和max之间
        currentHealth = Mathf.Clamp(currentHealth + amount, 0, maxHealth);
        Debug.Log(currentHealth+"/"+maxHealth);
    }
}

陷阱减血

陷阱挂载: Damagebale.cs

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

/// <summary>
/// 伤害陷阱相关
/// </summary>

public class Damagebale : MonoBehaviour
{
    private void OnTriggerStay2D(Collider2D other)
    {
        PlayerController pc = other.GetComponent<PlayerController>();
        if (pc != null)
        {
            pc.ChangeHealth(-1);
        }
    }
}

玩家挂载: PlayerController.cs 英汉:玩家控制

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

public class PlayerController : MonoBehaviour
{
    public float speed = 5f; //移动速度
    private int maxHealth = 5; //最大生命值
    private int currentHealth; //当前生命值
    public int MyMaxHealth { get { return maxHealth; } }
    public int MyCurrentHealth { get { return currentHealth; } }

    private float invincibleTime = 2f; //无敌时间2秒
    private float invincibleTimer;     //无敌计时器
    private bool isInvincible;         //是否无敌

    Rigidbody2D rbody; //刚体组件
    // Start is called before the first frame update
    void Start()
    {
        currentHealth = 2;
        invincibleTimer = 0;
        rbody = GetComponent<Rigidbody2D>();
    }
    // Update is called once per frame
    void Update()
    {
        //transform.Translate(transform.right * speed * Time.deltaTime);
        float moveX = Input.GetAxisRaw("Horizontal");
        float moveY = Input.GetAxisRaw("Vertical");
        Vector2 position = rbody.position;
        position.x += moveX * speed * Time.deltaTime;
        position.y += moveY * speed * Time.deltaTime;
        rbody.MovePosition(position);

        //无敌记时---------------------------------------------
        if (isInvincible)
        {
            invincibleTimer -= Time.deltaTime;
            if (invincibleTimer < 0)
            {
                isInvincible = false; //无敌时间结束
            }
        }
    }
    
   /// <summary>
   /// 改变玩家的生命值
   /// </summary>
   /// <param name="amount"></param>
    public void ChangeHealth(int amount)
    {
        if (amount < 0) //玩家收到伤害
        {
            if (isInvincible == true)  //玩家收到伤害时是无敌:跳出ChangeHealth
            {
                return;
            }
            isInvincible = true;    //玩家受到伤害时不是无敌:先改成无敌
            invincibleTimer = invincibleTime;     //不是无敌:再改设置计时时间再正常走ChangeHealth
        }

        //把玩家生命值约束在0和max之间
        currentHealth = Mathf.Clamp(currentHealth + amount, 0, maxHealth);
        Debug.Log(currentHealth+"/"+maxHealth);
    }
}

关系陷阱备注:

#玩家钢体持续监测属性修改: (不动也掉血)
	Ruby -- Sleeping Mode : Never Sleep
#陷阱平铺: (不变形)
	Damagebale (Texture 2D) import Settings -- Mesh Type : Full Rect  (这个图片可以平铺)
	Damagebale -- Draw Mode -- Tiled  (这个对象可以T箱拖动屏蔽)

机器人移动转向碰撞

EnemyController.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 敌人控制相关
/// </summary>
public class EnemyController : MonoBehaviour
{
    public float speed = 3;
    private Rigidbody2D rbody;
    public bool isVertical; //是否垂直方向移动
    private Vector2 moveDirection; //移动方向
    public float changeDirectionTime = 3; //切换方向时间2秒
    private float changeTimer;

    // Start is called before the first frame update
    void Start()
    {
        rbody = GetComponent<Rigidbody2D>();   //获取刚体    
        moveDirection = isVertical ? Vector2.up : Vector2.right; //如果时垂直移动,设定向上,否则设定向右
        changeTimer = changeDirectionTime;

    }

    // Update is called once per frame
    void Update()
    {
        changeTimer -= Time.deltaTime;
        if (changeTimer < 0 )
        {
            moveDirection *= -1; //切换方向
            changeTimer = changeDirectionTime;
        }
        Vector2 position = rbody.position; //敌人移动
        position.x += moveDirection.x * speed * Time.deltaTime;
        position.y += moveDirection.y * speed * Time.deltaTime;
        rbody.MovePosition(position);
    }

    // 敌人与玩家碰撞
    private void OnCollisionEnter2D(Collision2D other)
    {
        PlayerController pc = other.gameObject.GetComponent<PlayerController>();
        if (pc != null)
        {
            pc.ChangeHealth(-1);
        }
    }
}

草莓动画

选中一个草莓 – Ctrl+6(或Window/Animation/Animation) – Create – (Assets目录/Animatior/Items/idle.anim) – 修改帧数 – 设置关键帧属性

敌人动画

选中一个机器人 -- 没个方向拖入4帧的图片组成动画(创建4个目录上下左右)
缺一个向右的动画 :选中一个机器人 -- Ctrl+6 -- Create New Clip -- 起名walk_right -- 托入向左的4个图像然后做X轴翻转: Add Property -- Sprite Renderer -- Flip X -- 都勾起。

回到敌人Robot属性 -- Animator -- Controller -- Robot -- 创建一个混合树Walk,把Entry的默认动画设置为混合树
混合树Base Layer -- Walk  -- Inspector -- Blend Type : 2D simple Directoional 
混合树Base Layer -- Walk  -- Inspector -- 把上面的上下左右四个动画Add到混合树,分别赋值+1或-1。 完事这4个动画可以删除了,有混合树就行了。
混合树Base Layer : 添加两个参数moveX,moveY,fix
混合树Base Layer -- Walk->Fixed链接修理好的状态 -- 把过度时间去掉: Has Exit Time的勾选去掉 , Settings -- Fixed Duration的勾选去掉,Transtion Duration:0秒

敌人移动动画脚本:EnemyController.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 敌人控制相关
/// </summary>
public class EnemyController : MonoBehaviour
{
    public float speed = 3;
    private Rigidbody2D rbody; //刚体定义
    public bool isVertical; //是否垂直方向移动
    private Vector2 moveDirection; //移动方向
    public float changeDirectionTime = 3; //切换方向时间2秒
    private float changeTimer;

    private Animator anim;  //动画定义

    // Start is called before the first frame update
    void Start()
    {
        rbody = GetComponent<Rigidbody2D>();   //获取刚体
        anim = GetComponent<Animator>();       //获取动画
        moveDirection = isVertical ? Vector2.up : Vector2.right; //如果时垂直移动,设定向上,否则设定向右
        changeTimer = changeDirectionTime;

    }

    // Update is called once per frame
    void Update()
    {
        changeTimer -= Time.deltaTime;
        if (changeTimer < 0 )
        {
            moveDirection *= -1; //切换方向
            changeTimer = changeDirectionTime;
        }
        Vector2 position = rbody.position; //敌人移动
        position.x += moveDirection.x * speed * Time.deltaTime;
        position.y += moveDirection.y * speed * Time.deltaTime;
        rbody.MovePosition(position);
        //敌人移动动画
        anim.SetFloat("moveX",moveDirection.x);
        anim.SetFloat("moveY", moveDirection.y);
    }

    // 敌人与玩家碰撞
    private void OnCollisionEnter2D(Collision2D other)
    {
        PlayerController pc = other.gameObject.GetComponent<PlayerController>();
        if (pc != null)
        {
            pc.ChangeHealth(-1);
        }
    }
}

玩家移动动画

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

public class PlayerController : MonoBehaviour
{
    public float speed = 5f; //移动速度
    private int maxHealth = 5; //最大生命值
    private int currentHealth; //当前生命值
    public int MyMaxHealth { get { return maxHealth; } }
    public int MyCurrentHealth { get { return currentHealth; } }

    private float invincibleTime = 2f; //无敌时间2秒
    private float invincibleTimer;     //无敌计时器
    private bool isInvincible;         //是否无敌

    private Vector2 lookDirection = new Vector2(1, 0); //默认朝向右方

    Rigidbody2D rbody; //刚体组件
    Animator anim; //获取动画组
    // Start is called before the first frame update
    void Start()
    {
        currentHealth = 2;
        invincibleTimer = 0;
        rbody = GetComponent<Rigidbody2D>();
        anim = GetComponent<Animator>();
    }
    // Update is called once per frame
    void Update()
    {
        //transform.Translate(transform.right * speed * Time.deltaTime);
        float moveX = Input.GetAxisRaw("Horizontal");
        float moveY = Input.GetAxisRaw("Vertical");

        //角色方向更具前后左右来选中方向
        Vector2 moveVector = new Vector2(moveX, moveY);
        if (moveVector.x != 0 || moveVector.y != 0)
        {
            lookDirection = moveVector;
        }
        anim.SetFloat("Look X",lookDirection.x);
        anim.SetFloat("Look Y",lookDirection.y);
        //方向移动动画
        anim.SetFloat("Speed",moveVector.magnitude);

        //基础移动------------------------------------------------
        Vector2 position = rbody.position;
        //position.x += moveX * speed * Time.deltaTime;
        //position.y += moveY * speed * Time.deltaTime;
        position += moveVector * speed * Time.deltaTime;
        rbody.MovePosition(position);

        //无敌记时---------------------------------------------
        if (isInvincible)
        {
            invincibleTimer -= Time.deltaTime;
            if (invincibleTimer < 0)
            {
                isInvincible = false; //无敌时间结束
            }
        }
    }
    
   /// <summary>
   /// 改变玩家的生命值
   /// </summary>
   /// <param name="amount"></param>
    public void ChangeHealth(int amount)
    {
        if (amount < 0) //玩家收到伤害
        {
            if (isInvincible == true)  //玩家收到伤害时是无敌:跳出ChangeHealth
            {
                return;
            }
            isInvincible = true;    //玩家受到伤害时不是无敌:先改成无敌
            invincibleTimer = invincibleTime;     //不是无敌:再改设置计时时间再正常走ChangeHealth
        }

        //把玩家生命值约束在0和max之间
        currentHealth = Mathf.Clamp(currentHealth + amount, 0, maxHealth);
        Debug.Log(currentHealth+"/"+maxHealth);
    }
}

子弹

子弹脚本: BulletlconController.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 控制子弹的移动、碰撞
/// </summary>

public class BulletlconController : MonoBehaviour
{
    Rigidbody2D rbody;
    // Start is called before the first frame update
    void Awake()
    {
        rbody = GetComponent<Rigidbody2D>();
        Destroy(this.gameObject,2f); //多长时间后消失
    }

    /// <summary>
    /// 子弹移动
    /// </summary>
    /// <param name="moveDirection"></param>
    /// <param name="moveForce"></param>
    public void Move(Vector2 moveDirection, float moveForce)
    {
        rbody.AddForce(moveDirection * moveForce);
    }

    /// <summary>
    /// 子弹碰撞检测
    /// </summary>
    /// <param name="other"></param>
    void OnCollisionEnter2D(Collision2D other)
    {
        EnemyController ec = other.gameObject.GetComponent<EnemyController>();
        if (ec != null)
        {
            Debug.Log("子弹碰到了敌人");
            ec.Fixed(); //修复敌人
        }

        Destroy(this.gameObject);  //碰撞后消失
    }
}

机器人脚本(被修复)Damagebale.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 敌人控制相关
/// </summary>
public class EnemyController : MonoBehaviour
{
    public float speed = 3;
    private Rigidbody2D rbody; //刚体定义
    public bool isVertical; //是否垂直方向移动
    private Vector2 moveDirection; //移动方向
    public float changeDirectionTime = 3; //切换方向时间2秒
    private float changeTimer;

    private Animator anim;  //动画定义

    private bool isFixed ; //被修理过

    // Start is called before the first frame update
    void Start()
    {
        rbody = GetComponent<Rigidbody2D>();   //获取刚体
        anim = GetComponent<Animator>();       //获取动画
        moveDirection = isVertical ? Vector2.up : Vector2.right; //如果时垂直移动,设定向上,否则设定向右
        changeTimer = changeDirectionTime;
        isFixed = false;
    }

    // Update is called once per frame
    void Update()
    {
        if (isFixed)  return;  //如果被修复了就不执行下面的代码 
        changeTimer -= Time.deltaTime;
        if (changeTimer < 0 )
        {
            moveDirection *= -1; //切换方向
            changeTimer = changeDirectionTime;
        }
        Vector2 position = rbody.position; //敌人移动
        position.x += moveDirection.x * speed * Time.deltaTime;
        position.y += moveDirection.y * speed * Time.deltaTime;
        rbody.MovePosition(position);
        //敌人移动动画
        anim.SetFloat("moveX",moveDirection.x);
        anim.SetFloat("moveY", moveDirection.y);
    }

    // 敌人与玩家碰撞
    private void OnCollisionEnter2D(Collision2D other)
    {
        PlayerController pc = other.gameObject.GetComponent<PlayerController>();
        if (pc != null)
        {
            pc.ChangeHealth(-1);
        }
    }

    // 敌人与子弹的碰撞,被修复
    public void Fixed()
    {
        isFixed = true;
        rbody.simulated = false; //禁用物理
        anim.SetTrigger("fix");  //播放被修复的动画
    }
}

玩家控制子弹脚本:PlayerController.cs

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

public class PlayerController : MonoBehaviour
{
    public float speed = 5f; //移动速度
    private int maxHealth = 5; //最大生命值
    private int currentHealth; //当前生命值
    public int MyMaxHealth { get { return maxHealth; } }
    public int MyCurrentHealth { get { return currentHealth; } }

    private float invincibleTime = 2f; //无敌时间2秒
    private float invincibleTimer;     //无敌计时器
    private bool isInvincible;         //是否无敌

    private Vector2 lookDirection = new Vector2(1, 0); //默认朝向右方

    public GameObject bulletPrefab;   //获取子弹


    Rigidbody2D rbody; //刚体组件
    Animator anim; //获取动画组
    // Start is called before the first frame update
    void Start()
    {
        currentHealth = 2;
        invincibleTimer = 0;
        rbody = GetComponent<Rigidbody2D>();
        anim = GetComponent<Animator>();
    }
    // Update is called once per frame
    void Update()
    {
        //transform.Translate(transform.right * speed * Time.deltaTime);
        float moveX = Input.GetAxisRaw("Horizontal");
        float moveY = Input.GetAxisRaw("Vertical");

        //角色方向更具前后左右来选中方向
        Vector2 moveVector = new Vector2(moveX, moveY);
        if (moveVector.x != 0 || moveVector.y != 0)
        {
            lookDirection = moveVector;
        }
        anim.SetFloat("Look X",lookDirection.x);
        anim.SetFloat("Look Y",lookDirection.y);
        //方向移动动画
        anim.SetFloat("Speed",moveVector.magnitude);

        //基础移动------------------------------------------------
        Vector2 position = rbody.position;
        //position.x += moveX * speed * Time.deltaTime;
        //position.y += moveY * speed * Time.deltaTime;
        position += moveVector * speed * Time.deltaTime;
        rbody.MovePosition(position);

        //无敌记时---------------------------------------------
        if (isInvincible)
        {
            invincibleTimer -= Time.deltaTime;
            if (invincibleTimer < 0)
            {
                isInvincible = false; //无敌时间结束
            }
        }

        //按下J键,创建发射子弹
        if (Input.GetKeyDown(KeyCode.J))
        {
            anim.SetTrigger("Launch"); //播放发射动画
            GameObject bullet = Instantiate(bulletPrefab, rbody.position + Vector2.up * 0.5f,Quaternion.identity);
            BulletlconController bc = bullet.GetComponent<BulletlconController>();
            if (bc != null)
            {
                bc.Move(lookDirection, 300);
            }
        }
    }
    
   /// <summary>
   /// 改变玩家的生命值
   /// </summary>
   /// <param name="amount"></param>
    public void ChangeHealth(int amount)
    {
        if (amount < 0) //玩家收到伤害
        {
            if (isInvincible == true)  //玩家收到伤害时是无敌:跳出ChangeHealth
            {
                return;
            }
            isInvincible = true;    //玩家受到伤害时不是无敌:先改成无敌
            invincibleTimer = invincibleTime;     //不是无敌:再改设置计时时间再正常走ChangeHealth
        }

        //把玩家生命值约束在0和max之间
        currentHealth = Mathf.Clamp(currentHealth + amount, 0, maxHealth);
        Debug.Log(currentHealth+"/"+maxHealth);
    }
}


玩家挂载子弹设置

Roby -- Player Controller -- Bullet Prefab : UIBulletlcon   //挂载上子弹预制体
Roby -- Layer -- Add Layer -- User Layer8 : Player    //第8层添加一个player层
预制体UIBulletlcon -- Layer -- Add -- User Layer9 : Bullet    //第9层子弹
再各自选层(不要Default)
Edit -- Project Settings -- Physics 2D -- Layer Collision Matrix  //去掉层级碰撞勾选2个
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值