LoginSignup
2
2

More than 5 years have passed since last update.

Raycastのサンプル

Posted at

https://docs.unity3d.com/jp/530/Manual/CameraRays.html
https://docs.unity3d.com/jp/540/ScriptReference/Physics.Raycast.html

サンプル1

カメラからマウスの位置へ向かってレイを飛ばし、
ゲームオブジェクトにコライダがついていれば衝突物として判定する

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RayCast : MonoBehaviour {
    float rayRange = 100f; // 100m以上レイは伸びない
    void Update () {
        RaycastHit hit;
        // メインカメラからマウスの位置へレイをとばす
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        if(Physics.Raycast(ray, out hit, rayRange)){
            Debug.Log(hit.point);
        }
    }
}

Physics.Raycast(ray, out hit, 100)は、
Physics.Raycast(ray.origin, ray.direction, out hit, 100)と同じ

参考
Camera.ScreenPointToRay
https://docs.unity3d.com/ja/current/ScriptReference/Camera.ScreenPointToRay.html

サンプル2

解説:Let's Try: Shooting with Raycasts (Video)

構成
スクリーンショット 2017-10-31 18.55.16.png

イメージ
スクリーンショット 2017-10-31 19.00.17.png

カメラの中心からレイを飛ばし、
衝突物があれば、銃口から衝突物まで線を引く。
衝突物がなければ、レイを飛ばす限界まで線を引く。

RaycastShoot.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RaycastShoot : MonoBehaviour {

    public float fireRate = .25f;
    public float weaponRange = 50f;
    public float hitForce = 100f;
    public Transform gunEnd;

    private Camera fpsCamera;
    private WaitForSeconds shotDuration = new WaitForSeconds (.07f);
    private LineRenderer laserLine;
    private float nextFire;

    void Start () {
        laserLine = GetComponent<LineRenderer> ();
        fpsCamera = GetComponentInParent<Camera> ();
    }

    void Update () {
        if(Input.GetButtonDown("Fire1") && Time.time > nextFire){
            // 連射防止
            nextFire = Time.time + fireRate;

            StartCoroutine ("ShotEffect");

            // レイを飛ばす原点(カメラの中心)
            Vector3 rayOrigin = fpsCamera.ViewportToWorldPoint (new Vector3 (0.5f, 0.5f, 0));
            RaycastHit hit;

            // LineRenderer.SetPosition(index, vec3)
            laserLine.SetPosition (0, gunEnd.position); // 銃口から
            // ray origin, direction, return float, max distance
            if (Physics.Raycast (rayOrigin, fpsCamera.transform.forward, out hit, weaponRange)) {
                laserLine.SetPosition (1, hit.point);

                if (hit.rigidbody != null) {
                    // ヒットしたオブジェクトの背面ベクトル
                    hit.rigidbody.AddForce (-hit.normal * hitForce);
                }
            } else {
                laserLine.SetPosition (1, rayOrigin + (fpsCamera.transform.forward * weaponRange));
            }
        }
    }

    private IEnumerator ShotEffect() {
        laserLine.enabled = true;
        yield return shotDuration;
        laserLine.enabled = false;
    }

}

参考
LineRenderer.SetPosition
https://docs.unity3d.com/jp/540/ScriptReference/LineRenderer.SetPosition.html
RaycastHit-normal
https://docs.unity3d.com/ja/540/ScriptReference/RaycastHit-normal.html

デバッグ用にカメラの中心からレイを描く

RayViewer.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RayViewer : MonoBehaviour {

    public float weaponRange = 50f;
    private Camera fpsCamera;

    void Start () {
        fpsCamera = GetComponentInParent<Camera> ();
    }

    void Update () {
        Vector3 lineOrigin = fpsCamera.ViewportToWorldPoint(new Vector3(0.5f, 0.5f, 0.0f));
        Debug.DrawLine (lineOrigin, fpsCamera.transform.forward * weaponRange, Color.green);
    }
}
2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2