「Unity/3d/FPS」の版間の差分
提供: 初心者エンジニアの簡易メモ
(→銃オブジェクト追加) |
(→プレイヤーの移動) |
||
| 行71: | 行71: | ||
参考:https://xr-hub.com/archives/7782 | 参考:https://xr-hub.com/archives/7782 | ||
| + | |||
| + | ==透明な弾を打つ== | ||
| + | |||
| + | #AssetsStoreで"War FX"を検索 | ||
| + | #以下csをGunに貼り付ける | ||
| + | <pre> | ||
| + | using System.Collections; | ||
| + | using System.Collections.Generic; | ||
| + | using UnityEngine; | ||
| + | public class RayGunController : MonoBehaviour | ||
| + | { | ||
| + | public enum ShootMode { AUTO, SEMIAUTO } | ||
| + | public bool shootEnabled = true; | ||
| + | [SerializeField] | ||
| + | ShootMode shootMode = ShootMode.AUTO; | ||
| + | [SerializeField] | ||
| + | int maxAmmo = 1000; | ||
| + | [SerializeField] | ||
| + | int damage = 1; | ||
| + | [SerializeField] | ||
| + | float shootInterval = 0.15f; | ||
| + | [SerializeField] | ||
| + | float shootRange = 50; | ||
| + | [SerializeField] | ||
| + | Vector3 muzzleFlashScale; | ||
| + | [SerializeField] | ||
| + | GameObject muzzleFlashPrefab; | ||
| + | [SerializeField] | ||
| + | GameObject hitEffectPrefab; | ||
| + | bool shooting = false; | ||
| + | int ammo; | ||
| + | GameObject muzzleFlash; | ||
| + | GameObject hitEffect; | ||
| + | public int Ammo | ||
| + | { | ||
| + | set | ||
| + | { | ||
| + | ammo = Mathf.Clamp(value, 0, maxAmmo); | ||
| + | } | ||
| + | get | ||
| + | { | ||
| + | return ammo; | ||
| + | } | ||
| + | } | ||
| + | void Start() | ||
| + | { | ||
| + | InitGun(); | ||
| + | } | ||
| + | void Update() | ||
| + | { | ||
| + | if (shootEnabled & ammo > 0 & GetInput()) | ||
| + | { | ||
| + | StartCoroutine(ShootTimer()); | ||
| + | } | ||
| + | } | ||
| + | void InitGun() | ||
| + | { | ||
| + | Ammo = maxAmmo; | ||
| + | } | ||
| + | bool GetInput() | ||
| + | { | ||
| + | switch (shootMode) | ||
| + | { | ||
| + | case ShootMode.AUTO: | ||
| + | return Input.GetMouseButton(0); | ||
| + | case ShootMode.SEMIAUTO: | ||
| + | return Input.GetMouseButtonDown(0); | ||
| + | } | ||
| + | return false; | ||
| + | } | ||
| + | IEnumerator ShootTimer() | ||
| + | { | ||
| + | if (!shooting) | ||
| + | { | ||
| + | shooting = true; | ||
| + | if (muzzleFlashPrefab != null) | ||
| + | { | ||
| + | if (muzzleFlash != null) | ||
| + | { | ||
| + | muzzleFlash.SetActive(true); | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | muzzleFlash = Instantiate(muzzleFlashPrefab, transform.position, transform.rotation); | ||
| + | muzzleFlash.transform.SetParent(gameObject.transform); | ||
| + | muzzleFlash.transform.localScale = muzzleFlashScale; | ||
| + | } | ||
| + | } | ||
| + | Shoot(); | ||
| + | yield return new WaitForSeconds(shootInterval); | ||
| + | if (muzzleFlash != null) | ||
| + | { | ||
| + | muzzleFlash.SetActive(false); | ||
| + | } | ||
| + | if (hitEffect != null) | ||
| + | { | ||
| + | if (hitEffect.activeSelf) | ||
| + | { | ||
| + | hitEffect.SetActive(false); | ||
| + | } | ||
| + | } | ||
| + | shooting = false; | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | yield return null; | ||
| + | } | ||
| + | } | ||
| + | void Shoot() | ||
| + | { | ||
| + | Ray ray = new Ray(transform.position, transform.forward); | ||
| + | RaycastHit hit; | ||
| + | if (Physics.Raycast(ray, out hit, shootRange)) | ||
| + | { | ||
| + | if (hitEffectPrefab != null) | ||
| + | { | ||
| + | if (hitEffect != null) | ||
| + | { | ||
| + | hitEffect.transform.position = hit.point; | ||
| + | hitEffect.transform.rotation = Quaternion.FromToRotation(Vector3.forward, hit.normal); | ||
| + | hitEffect.SetActive(true); | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | hitEffect = Instantiate(hitEffectPrefab, hit.point, Quaternion.identity); | ||
| + | } | ||
| + | } | ||
| + | Debug.Log("hit=" + hit.collider.gameObject.name); // こんな感じで敵のオブジェクト名取得 | ||
| + | } | ||
| + | Ammo--; | ||
| + | } | ||
| + | } | ||
| + | </pre> | ||
| + | |||
| + | 参考:https://unity.moon-bear.com/zombie-slayer/shoot-and-effect/ | ||
==プレイヤーの移動== | ==プレイヤーの移動== | ||
2020年6月10日 (水) 14:27時点における最新版
FPS視点カメラ
- ヒエラルキーからCreateEmptyして新規オブジェクトを作成しオブジェクト名を"Player"とする
- MainCameraのオブジェクト名を"FSPCamera"へ変更
- Playerの下にFSPCameraを移動
- 以下csを作成してFPSCameraへドラッグ
FPSCamera.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace FPS
{
public class FPSCamera : MonoBehaviour
{
private Transform _camTransform;
//マウス操作の始点
private Vector3 _startMousePos;
//カメラ回転の始点情報
private Vector3 _presentCamRotation;
void Start()
{
_camTransform = this.gameObject.transform;
}
void Update()
{
//カメラの回転 マウス
CameraRotationMouseControl();
}
//カメラの回転 マウス
private void CameraRotationMouseControl()
{
if (Input.GetMouseButtonDown(0))
{
_startMousePos = Input.mousePosition;
_presentCamRotation.x = _camTransform.transform.eulerAngles.x;
_presentCamRotation.y = _camTransform.transform.eulerAngles.y;
}
if (Input.GetMouseButton(0))
{
//(移動開始座標 - マウスの現在座標) / 解像度 で正規化
float x = (_startMousePos.x - Input.mousePosition.x) / Screen.width;
float y = (_startMousePos.y - Input.mousePosition.y) / Screen.height;
//回転開始角度 + マウスの変化量 * 90
float eulerX = _presentCamRotation.x + y * 90.0f;
float eulerY = _presentCamRotation.y + x * 90.0f;
_camTransform.rotation = Quaternion.Euler(eulerX, eulerY, 0);
}
}
}
}
参考:https://qiita.com/Nekomasu/items/0a6aaf1f595cf05fbd0d
参考:https://xr-hub.com/archives/7782
銃オブジェクト追加
- AssetStoreで銃(例:"FPS-AKM"で出てくる)を追加
- 銃をヒエラルキーに追加し、オブジェクト名を"Gun"に変更する
- FPSCameraの子にGunを移動
参考:https://xr-hub.com/archives/7782
透明な弾を打つ
- AssetsStoreで"War FX"を検索
- 以下csをGunに貼り付ける
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RayGunController : MonoBehaviour
{
public enum ShootMode { AUTO, SEMIAUTO }
public bool shootEnabled = true;
[SerializeField]
ShootMode shootMode = ShootMode.AUTO;
[SerializeField]
int maxAmmo = 1000;
[SerializeField]
int damage = 1;
[SerializeField]
float shootInterval = 0.15f;
[SerializeField]
float shootRange = 50;
[SerializeField]
Vector3 muzzleFlashScale;
[SerializeField]
GameObject muzzleFlashPrefab;
[SerializeField]
GameObject hitEffectPrefab;
bool shooting = false;
int ammo;
GameObject muzzleFlash;
GameObject hitEffect;
public int Ammo
{
set
{
ammo = Mathf.Clamp(value, 0, maxAmmo);
}
get
{
return ammo;
}
}
void Start()
{
InitGun();
}
void Update()
{
if (shootEnabled & ammo > 0 & GetInput())
{
StartCoroutine(ShootTimer());
}
}
void InitGun()
{
Ammo = maxAmmo;
}
bool GetInput()
{
switch (shootMode)
{
case ShootMode.AUTO:
return Input.GetMouseButton(0);
case ShootMode.SEMIAUTO:
return Input.GetMouseButtonDown(0);
}
return false;
}
IEnumerator ShootTimer()
{
if (!shooting)
{
shooting = true;
if (muzzleFlashPrefab != null)
{
if (muzzleFlash != null)
{
muzzleFlash.SetActive(true);
}
else
{
muzzleFlash = Instantiate(muzzleFlashPrefab, transform.position, transform.rotation);
muzzleFlash.transform.SetParent(gameObject.transform);
muzzleFlash.transform.localScale = muzzleFlashScale;
}
}
Shoot();
yield return new WaitForSeconds(shootInterval);
if (muzzleFlash != null)
{
muzzleFlash.SetActive(false);
}
if (hitEffect != null)
{
if (hitEffect.activeSelf)
{
hitEffect.SetActive(false);
}
}
shooting = false;
}
else
{
yield return null;
}
}
void Shoot()
{
Ray ray = new Ray(transform.position, transform.forward);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, shootRange))
{
if (hitEffectPrefab != null)
{
if (hitEffect != null)
{
hitEffect.transform.position = hit.point;
hitEffect.transform.rotation = Quaternion.FromToRotation(Vector3.forward, hit.normal);
hitEffect.SetActive(true);
}
else
{
hitEffect = Instantiate(hitEffectPrefab, hit.point, Quaternion.identity);
}
}
Debug.Log("hit=" + hit.collider.gameObject.name); // こんな感じで敵のオブジェクト名取得
}
Ammo--;
}
}
参考:https://unity.moon-bear.com/zombie-slayer/shoot-and-effect/
プレイヤーの移動
- RigidbodyをPlayerに追加
- 下に落ちてしまう場合は、床をPlaneで作り、床にAddComponentでBoxColliderを追加し、PlayerにもCapsuleColliderを追加する
- 以下のようなPlayerController.csを作る
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
Rigidbody m_Rigidbody;
void Start()
{
// 自分のRigidbodyを取ってくる
m_Rigidbody = GetComponent<Rigidbody>();
}
void Update()
{
// 十字キーで首を左右に回す
if (Input.GetKey(KeyCode.RightArrow))
{
transform.Rotate(new Vector3(0.0f, 1.0f, 0.0f));
}
if (Input.GetKey(KeyCode.LeftArrow))
{
transform.Rotate(new Vector3(0.0f, -1.0f, 0.0f));
}
// WASDで移動する
float x = 0.0f;
float z = 0.0f;
if (Input.GetKey(KeyCode.D))
{
x += 1.0f;
}
if (Input.GetKey(KeyCode.A))
{
x -= 1.0f;
}
if (Input.GetKey(KeyCode.W))
{
z += 1.0f;
}
if (Input.GetKey(KeyCode.S))
{
z -= 1.0f;
}
m_Rigidbody.velocity = new Vector3(x, 0.0f, z);
}
}
