注意碰撞体。
在VFX文件夹下找到子弹的素材,调整素材的大小。
为素材添加刚体属性、碰撞属性。注意Rigidbody2D需要把重力设置为0,并冻结z轴。
将设置好的子弹素材放入Prefab中,添加脚本ProjectTile如下:
1 using System.Collections; 2 using System.Collections.Generic; 3 using UnityEngine; 4 5 public class ProjectTile : MonoBehaviour 6 { 7 private Rigidbody2D _rigidbody2D; 8 9 //初始化的时候使用awake,防止内存分配先后导致的游戏错误 10 private void Awake() 11 { 12 _rigidbody2D = GetComponent<Rigidbody2D>(); 13 } 14 15 //子弹的发射动作 16 public void Launch(Vector2 direction, float force) 17 { 18 _rigidbody2D.AddForce(direction * force); 19 } 20 21 //碰撞检测 22 public void OnCollisionEnter2D(Collision2D collision) 23 { 24 Destroy(gameObject); 25 } 26 27 28 // Update is called once per frame 29 void Update() 30 { 31 32 } 33 }
然后进入PlayerController进行进一步的编辑。
首先在Update方法中添加按键响应
1 if(Input.GetKeyDown(KeyCode.Space)) 2 { 3 LaunchProjectile(); 4 }
这里我选择用空格键来发射子弹。
编写LaunchProjectile方法
1 private void LaunchProjectile() 2 { 3 GameObject _projectileGameObject = null; 4 5 //角色朝向为下时,让子弹从角色的碰撞体下方发射//其他朝向时从角色体中间发射(*0.5f) 6 if (lookDir == Vector2.down) 7 { 8 //instantiate是对物品进行复制操作的函数 9 _projectileGameObject = Instantiate(projectilePrefab, rbody.position + Vector2.down, Quaternion.identity); 10 } 11 else 12 { 13 _projectileGameObject = Instantiate(projectilePrefab, rbody.position + Vector2.up * 0.5f, Quaternion.identity); 14 } 15 16 //获取相应组件 17 ProjectTile projectTile = _projectileGameObject.GetComponent<ProjectTile>(); 18 projectTile.Launch(lookDir, 300); 19 }
projectilePrefab为在前面声明的GameObject公有变量。
Instantiate函数实例化是将original对象的所有子物体和子组件完全复制,成为一个新的对象。
unity API文档解释如下:
*注意,因为设置了碰撞检测,所以一定要检查Player的碰撞体的范围是否会影响子弹的发射。
首先添加粒子
将其重新命名为Smoke。
将VFX文件夹中的ParticleSpriteAtlas进行切割,将烟雾导入到Smoke中
调整Start Frame,使得两张图片随机出现。
调整基本属性
调整形状
调整阶段颜色使得烟雾有消失的效果 rpg -> 255 185 0
新建粒子,重新命名为FixedEffect
将其Transform中的position z轴值更改为0
Rotation中x的值由-90改为0
设置粒子信息如下
为enemy添加fixed动画
并在Animator中将状态进行绑定
并添加一个新的触发器Trigger,命名为fixed
更改联系,使得状态能够迅速转变
在enemyController中进行脚本的编写
1 using System.Collections; 2 using System.Collections.Generic; 3 using UnityEngine; 4 5 public class EnemyController : MonoBehaviour 6 { 7 public float speed = 2f; 8 //多少时间发生方向的反转 9 public float timeToChangeDirection = 2f; 10 //判断方向的变量 11 public bool horizontal; 12 13 //时间控制器 14 private float remainingTime; 15 //方向控制->初始方向是向右 16 private Vector2 _direction = Vector2.left; 17 18 //刚体 动画控制 19 private Rigidbody2D _rigidBody2D; 20 private Animator _animator; 21 22 //和平衡树中对应 23 private static readonly int lookx = Animator.StringToHash("lookx"); 24 private static readonly int looky = Animator.StringToHash("looky"); 25 26 //敌人击中粒子 27 private bool _repaired; 28 public GameObject smoke; 29 public ParticleSystem fixedEffect; 30 31 // Start is called before the first frame update 32 void Start() 33 { 34 _rigidBody2D = GetComponent<Rigidbody2D>(); 35 _animator = GetComponent<Animator>(); 36 37 //时间初始化 timer 38 remainingTime = timeToChangeDirection; 39 //判断方向是否水平,并进行判断和更改 40 _direction = horizontal ? Vector2.left : Vector2.down; 41 } 42 43 // Update is called once per frame 44 void Update() 45 { 46 if (_repaired) return; 47 48 //做倒计时 49 remainingTime -= Time.deltaTime; 50 51 if (remainingTime <= 0) 52 { 53 remainingTime = timeToChangeDirection; 54 //****改变方向**** 55 _direction *= -1; 56 } 57 58 _animator.SetFloat(lookx, _direction.x); 59 _animator.SetFloat(looky, _direction.y); 60 61 62 } 63 64 //对刚体的操作 65 private void FixedUpdate() 66 { 67 _rigidBody2D.MovePosition(_rigidBody2D.position + _direction * speed * Time.deltaTime); 68 } 69 70 private void OnCollisionEnter2D(Collision2D collision) 71 { 72 if(_repaired) 73 { 74 return; 75 } 76 77 PlayerContal controller = collision.collider.GetComponent<PlayerContal>(); 78 79 //判断人物控制是否为空,如果不为空,则执行掉血的操作 80 if(controller) 81 { 82 controller.ChangedHealth(-1); 83 } 84 } 85 86 //** 87 public void Fixed() 88 { 89 90 _animator.SetTrigger("fixed"); 91 92 //烟雾粒子停止播放 93 smoke.SetActive(false); 94 95 //产生爆炸效果 96 Instantiate(fixedEffect, _rigidBody2D.position + Vector2.up * 0.5f, Quaternion.identity); 97 98 //停止刚体的运动 99 _rigidBody2D.simulated = false; 100 101 //被击中状态 102 _repaired = true; 103 //-》取消碰撞检测 104 105 } 106 107 }
ProjecTile.cs
1 using System.Collections; 2 using System.Collections.Generic; 3 using UnityEngine; 4 5 public class ProjectTile : MonoBehaviour 6 { 7 private Rigidbody2D _rigidbody2D; 8 9 //初始化的时候使用awake,防止内存分配先后导致的游戏错误 10 private void Awake() 11 { 12 _rigidbody2D = GetComponent<Rigidbody2D>(); 13 } 14 15 //子弹的发射动作 16 public void Launch(Vector2 direction, float force) 17 { 18 _rigidbody2D.AddForce(direction * force); 19 } 20 21 //碰撞检测 22 public void OnCollisionEnter2D(Collision2D collision) 23 { 24 EnemyController enemyController = collision.collider.GetComponent<EnemyController>(); 25 26 //判断EnemyController是否实例化好了 27 if(enemyController) 28 { 29 //调用方法 30 enemyController.Fixed(); 31 } 32 33 Destroy(gameObject); 34 } 35 36 37 // Update is called once per frame 38 void Update() 39 { 40 41 } 42 }