笔者刚刚接触unity,跟着B站上的教程学着做了一个小项目,若有不足,请各位大佬多多指教。
视频教程网址:
https://www.bilibili.com/video/BV1V4411W787?p=6&spm_id_from=pageDriver
项目预览
素材搜集:Window-general-Assert store
导入后可在assert文件夹中查看
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()
{
float moveX = Input.GetAxisRaw("Horizontal");//control horizon move A:-1 D:1 else: 0
float moveY = Input.GetAxisRaw("Vertical");//control vertical move W:1 S:-1 else 0;
Vector2 position = transform.position;
position.x += moveX*speed*Time.deltaTime;
position.y += moveY * speed * Time.deltaTime;
transform.position = position;
}
}
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()
{
float moveX = Input.GetAxisRaw("Horizontal");//control horizon move A:-1 D:1 else: 0
float moveY = Input.GetAxisRaw("Vertical");//control vertical move W:1 S:-1 else 0;
Vector2 position = rBody.position;
position.x += moveX*speed*Time.fixedDeltaTime;
position.y += moveY * speed * Time.fixedDeltaTime;
rBody.MovePosition(position);
}
}
修改为刚体的位置,并且使用fixedDeltaTime替换DeltaTime
import package cinemaMachine
GameObject-cinemaMachine-2dCamera
将人物添加到相机的follow中
添加tilemapcollider
将除了水面以外 的瓦片 collidertype 都设为none
左侧创建新建空物体,取名为cameraConfirmer
为这个物体添加组件:Polygon Collider
编辑边界
在原相机中extension tools添加camera collider,把自己写的放进去。
confiner中点击istrigger,避免将人物弹出**(bug 4: 两者不兼容)**
public class PlayerController : MonoBehaviour
{
public float speed = 5f;
private float MaxHealth = 5;
private float MinHealth = 0;
private float currHealth ;
public float getMaxHealth()
{
return MaxHealth;
}
public float getMinHealth()
{
return MinHealth;
}
public float getCurrHealth()
{
return currHealth;
}
Rigidbody2D rBody;//刚体组件
// Start is called before the first frame update
void Start()
{
this.currHealth = 2;
rBody=GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
float moveX = Input.GetAxisRaw("Horizontal");//control horizon move A:-1 D:1 else: 0
float moveY = Input.GetAxisRaw("Vertical");//control vertical move W:1 S:-1 else 0;
Vector2 position = rBody.position;
position.x += moveX * speed * Time.fixedDeltaTime;
position.y += moveY * speed * Time.fixedDeltaTime;
rBody.MovePosition(position);
}
public void changeHealth(float add)
{
currHealth=Mathf.Clamp(add+currHealth, 0, MaxHealth);//玩家生命值约束在0与Maxhealth之间
}
}
新建脚本 collectable.cs
private void OnTriggerEnter2D(Collider2D other)
{
PlayerController player = other.GetComponent<PlayerController>();
if (player != null)
{
Debug.Log("玩家碰到草莓");
Debug.Log(player.getCurrHealth() + "/" + 5);
if (player.getCurrHealth() < player.getMaxHealth())
{
player.changeHealth(2);
Debug.Log(player.getCurrHealth() + "/" + 5);
Destroy(this.gameObject);//拾取草莓后摧毁草莓
}
}
}
private void OnTriggerStay2D(Collider2D other)
{
PlayerController player = other.GetComponent<PlayerController>();
if (player != null)
{
Debug.Log("玩家碰到陷阱");
Debug.Log(player.getCurrHealth() + "/" + 5);
if (player.getCurrHealth() > 0)
{
player.changeHealth(-1);
Debug.Log(player.getCurrHealth() + "/" + 5);
}
}
}//注意方法为OnTriggerStay2D,可实现持续收到伤害
private float invincibleTimer;
private float invincibleTime=2f ;
private bool isinvincible=false;
//
if (isinvincible)
{
invincibleTimer -= Time.deltaTime;
if(invincibleTimer < 0)
isinvincible=false;//两秒以后取消无敌状态
}
//在update函数中
public void changeHealth(float add)
{
if(add<0)
{
if (isinvincible)
{
return;
}
isinvincible = true;
invincibleTimer = invincibleTime;
}
currHealth=Mathf.Clamp(add+currHealth, 0, MaxHealth);//玩家生命值约束在0与Maxhealth之间
}
//修改changeHealth函数
实现人物站在陷阱里也能收到伤害
人物刚体选择neverawake
伤害区域的扩充
选中伤害图片-drawmode-tiled平铺
1,给敌人加上刚体与碰撞,重力设为0;
2,编辑脚本EnemyController
public class EnemyController : MonoBehaviour
{
public float changeDirectionTime = 2f;//改变方向的时间
public float changeTimer;//改变方向的计时器
public float speed = 3f;
public bool isVertical;//是否垂直方向移动
Rigidbody2D rbody;
private Vector2 moveDirection;//移动方向
// 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*Time.deltaTime;
position.y += moveDirection.y * Time.deltaTime;
rbody.MovePosition(position);
}
///
/// 与玩家的碰撞检测
///
///
private void OnCollisionEnter2D(Collision2D collision)//碰撞体检测,不会穿过,要求两刚体之间
{
PlayerController pc = collision.gameObject.GetComponent<PlayerController>();
if (pc != null)
{
pc.changeHealth(-1);
}
}
}
public class EnemyController : MonoBehaviour
{
public float changeDirectionTime = 2f;//改变方向的时间
public float changeTimer;//改变方向的计时器
public float speed = 3f;
public bool isVertical;//是否垂直方向移动
Rigidbody2D rbody;
private Vector2 moveDirection;//移动方向
// Start is called before the first frame update
private Animator animator;
void Start()
{
rbody= GetComponent<Rigidbody2D>();
animator= 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*Time.deltaTime;
position.y += moveDirection.y * Time.deltaTime;
rbody.MovePosition(position);
animator.SetFloat("moveX",moveDirection.x);
animator.SetFloat("moveY", moveDirection.y);
}
///
/// 与玩家的碰撞检测
///
///
private void OnCollisionEnter2D(Collision2D collision)//碰撞体检测,不会穿过,要求两刚体之间
{
PlayerController pc = collision.gameObject.GetComponent<PlayerController>();
if (pc != null)
{
pc.changeHealth(-1);
}
}
}
public class PlayerController : MonoBehaviour
{
public float speed = 5f;
private float MaxHealth = 5;
private float MinHealth = 0;
private float currHealth ;
private float invincibleTimer;
private float invincibleTime=2f ;
private bool isinvincible=false;
private Animator animator;//动画机
private Vector2 lookDirection = new Vector2(1, 0);//初始朝向默认为向右
public float getMaxHealth()
{
return MaxHealth;
}
public float getMinHealth()
{
return MinHealth;
}
public float getCurrHealth()
{
return currHealth;
}
Rigidbody2D rBody;//刚体组件
// Start is called before the first frame update
void Start()
{
this.currHealth = 2;
invincibleTimer = 0;
rBody=GetComponent<Rigidbody2D>();
animator = GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
float moveX = Input.GetAxisRaw("Horizontal");//control horizon move A:-1 D:1 else: 0
float moveY = Input.GetAxisRaw("Vertical");//control vertical move W:1 S:-1 else 0;
//获取朝向:
Vector2 moveVector= new Vector2(moveX, moveY);
if(moveX!=0 || moveY != 0)//至少一个不为零(按下了键盘)
{
lookDirection = moveVector;
}
animator.SetFloat("Look X",moveVector.x);
animator.SetFloat("Look Y", moveVector.y);
animator.SetFloat("Speed", moveVector.magnitude);//向量的模
//控制移动
Vector2 position = rBody.position;
//position.x += moveX*speed*Time.fixedDeltaTime;
//position.y += moveY * speed * Time.fixedDeltaTime;
position += moveVector*speed*Time.deltaTime;
rBody.MovePosition(position);
//控制无敌时间
if (isinvincible)
{
invincibleTimer -= Time.deltaTime;
if(invincibleTimer < 0)
isinvincible=false;//两秒以后取消无敌状态
}
}
public void changeHealth(float add)
{
if(add<0)
{
if (isinvincible)
{
return;
}
isinvincible = true;
invincibleTimer = invincibleTime;
}
currHealth=Mathf.Clamp(add+currHealth, 0, MaxHealth);//玩家生命值约束在0与Maxhealth之间
Debug.Log("当前生命值" + currHealth);
}
}
将子弹拖入场景,加上刚体与碰撞,重力设为零,不加z旋转,不勾选 isTrigger
添加脚本 bulletController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BulletController : MonoBehaviour
{
private Rigidbody2D rb;
private void Awake()
{
rb = GetComponent<Rigidbody2D>();//优先于start
}
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
public void Move(Vector2 moveDirection, float moveForce)
//发射方法
{
rb.AddForce(moveDirection*moveForce);
}
}
修改图层与碰撞
右上角layer图层添加 player与bullet层
edit-preference-2D physical 修改碰撞:player与bullet之间,bullet与bullet之间禁止碰撞
添加enemy逻辑
public void Fixed()
{
rbody.simulated = false;//禁用物理模拟
animator.SetTrigger("fixed");//播放被修复的动画
isfixed = true;
}
plyercontroller 添加发射逻辑与动画
if (Input.GetKeyDown(KeyCode.J))
{
animator.SetTrigger("Launch");
GameObject bullet = Instantiate(bulletPrefab, rBody.position+Vector2.up *0.4f ,Quaternion.identity);
//默认方向,四元数,参数分别为预制体类别,产生出来的位置,旋转的初始角度
BulletController bc=bullet.GetComponent<BulletController>();
if (bc != null)
{
bc.Move(lookDirection, 300);
}
}
https://www.bilibili.com/video/BV1V4411W787?p=15
右侧列表-右键新建ui-image
将要添加的图片加进去
调整缩放模式convas-scale with screen size
调整血条:filed, horizontal
链接如下,需要补充。
B站教程
本项目github网址
感谢大家阅读!!!