您的位置:首页 > 移动开发 > Unity3D

Unity2D - 5. 向鼠标点击处发射子弹

2018-03-21 11:37 1356 查看
在大概解决了人物移动方案之后,可以添加发射子弹的功能,大概步骤如下

新建子弹的预制件

添加触发发射子弹的函数

实例化子弹对象

设置子弹的移动方向

设置子弹的消失条件

其中需要考虑的一点是如何将鼠标在屏幕上点击的位置转换为世界坐标的位置

效果图



子弹预制件

新建预制件
Resoures\Prefabs\Bullet
,设置一个小黑点的sprite,添加
Circle Collider 2D
Rigidbody 2D


添加脚本

// Bullet.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Bullet : MonoBehaviour {

[HideInInspector]public float speed = 0.5f;
[HideInInspector]public Vector2 direction = Vector2.zero;

void Start () {

}

void FixedUpdate () {
if (direction != Vector2.zero && !DetectCollider()) {
transform.Translate(direction * speed);
} else {
Destroy(this.gameObject);
}
}

bool DetectCollider() {
return Physics2D.Raycast((Vector2)transform.position, direction, speed, 1);
}

public void MoveTo(Vector3 dest) {
direction = (Vector2)(dest - transform.position).normalized;
}
}


同之前的人物移动方式相似,指定一个direction,每次移动,不同的是在检测到碰撞时会销毁

控制发射子弹

附加给player对象

// Shoot.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Shoot : MonoBehaviour {

GameObject bullet;
Camera mainCamera;
Move player;
float fireOffsetFromPlayer;
float coldDown = 0;
float fireSpeed = 0.5f;

// Use this for initialization
void Start () {
bullet = (GameObject)Resources.Load("Prefabs/Bullet");
mainCamera = GameObject.Find("Camera").GetComponent<Camera>();
player = GameObject.Find("player").GetComponent<Move>();
coldDown = fireSpeed;
}

// Update is called once per frame
void FixedUpdate () {
if (Input.GetMouseButton(0)) {
if (coldDown >= fireSpeed) {
Vector3 mousePosition = ScreenToWorldPoint(Input.mousePosition);
GameObject theBullet = Instantiate(bullet, GetFirePosition(mousePosition), Quaternion.identity);
theBullet.GetComponent<Bullet>().MoveTo(mousePosition);
coldDown = 0;
}
coldDown += Time.fixedDeltaTime;
}
}

public Vector3 ScreenToWorldPoint(Vector3 mousePosition) {
Vector3 screenPos = mainCamera.WorldToScreenPoint(transform.position);
mousePosition.z = screenPos.z;
Vector3 worldPos = mainCamera.ScreenToWorldPoint(mousePosition);
return worldPos;
}

Vector3 GetFirePosition(Vector3 mousePosition) {
fireOffsetFromPlayer = player.radius * 2;
Vector3 playerPosition = player.GetPosition();
Vector3 fireOffset = (mousePosition - playerPosition).normalized;
fireOffset.x *= fireOffsetFromPlayer;
fireOffset.y *= fireOffsetFromPlayer;
return fireOffset + playerPosition;
}
}


bullet
为存储加载预制件后的对象原本

mainCamera
为摄像机,用于确定鼠标点击位置在世界坐标系中的坐标

player
为游戏角色,这里还没有对控制进行整合,结构比较蠢,请无视

fireOffsetFromPlayer
为子弹出现地点距离人物中心的距离,如果子弹从人物中心点发射,会在碰撞到人物的碰撞体边界时消失

coldDown
为射击冷却状态

fireSpeed
为射速(每n秒一发)

大概效果为:

按住鼠标, 会在人物周围(以人物中心为圆心,鼠标方向为方向)开火,子弹飞向鼠标点击的位置,之后如果碰撞到墙体消失

对于需要固定开火位置的,需要手动调整

一些需要注意的点:

使用
GameObject bullet = (GameObject)Resources.Load("Prefabs/Bullet");
来加载预制件

使用
GameObject.Find("ObjectName");
来寻找游戏对象

使用
GameObject theBullet = Instantiate(bullet, GetFirePosition(mousePosition), Quaternion.identity);
来实例化游戏对象并获取句柄

ScreenToWorldPoint()
内,仅使用Vector2会出错
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Unity2D