facebook twitter hatena line email

Unity/3d/FPS

提供: 初心者エンジニアの簡易メモ
移動: 案内検索

FPS視点カメラ

  1. ヒエラルキーからCreateEmptyして新規オブジェクトを作成しオブジェクト名を"Player"とする
  2. MainCameraのオブジェクト名を"FSPCamera"へ変更
  3. Playerの下にFSPCameraを移動
  4. 以下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

銃オブジェクト追加

  1. AssetStoreで銃(例:"FPS-AKM"で出てくる)を追加
  2. 銃をヒエラルキーに追加し、オブジェクト名を"Gun"に変更する
  3. FPSCameraの子にGunを移動

参考:https://xr-hub.com/archives/7782

透明な弾を打つ

  1. AssetsStoreで"War FX"を検索
  2. 以下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/

プレイヤーの移動

  1. RigidbodyをPlayerに追加
  2. 下に落ちてしまう場合は、床をPlaneで作り、床にAddComponentでBoxColliderを追加し、PlayerにもCapsuleColliderを追加する
  3. 以下のような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);
	}
}

参考:http://chungames.hateblo.jp/entry/2016/07/31/201807