//tips
//アイテムに飛び道具を採用する
先のアイテムはrodで殴ることでダメージを与えたが、今度は飛び道具でダメージを与えていく。
まずはprefabでBulletを作成し、BulletにBulletAttackのスクリプトをアタッチ。
using UnityEngine;
using System.Collections;
public class BulletAttack : MonoBehaviour
{
void OnCollisionEnter(Collision col)
{
if (col.gameObject.tag == "Enemy")
{
Destroy(gameObject);
//Destroy(col.gameObject);
Decoy decoy = col.gameObject.GetComponent<Decoy>();
decoy.OneDamage();
}
}
}
次にBulletを飛ばす仕組みを整えていく。下記のスクリプトをベースに変更を加えていく。
using UnityEngine;
using System.Collections;
public class AddForceBullet : MonoBehaviour
{
// カーソルに使用するテクスチャ
[SerializeField]
private Texture2D cursor;
// 弾のゲームオブジェクト
[SerializeField]
private GameObject bulletPrefab;
// 銃口
[SerializeField]
private Transform muzzle;
// 弾を飛ばす力
[SerializeField]
private float bulletPower = 500f;
void Start()
{
// カーソルを自前のカーソルに変更
Cursor.SetCursor(cursor, new Vector2(cursor.width / 2, cursor.height / 2), CursorMode.ForceSoftware);
}
void Update()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
transform.rotation = Quaternion.LookRotation(ray.direction);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 1f, LayerMask.GetMask("Gun")))
{
Cursor.visible = false;
}
else
{
Cursor.visible = true;
}
// マウスの左クリックで撃つ
if (Input.GetButtonDown("Fire1"))
{
Shot();
}
}
// 敵を撃つ
void Shot()
{
var bulletInstance = Instantiate<GameObject>(bulletPrefab, muzzle.position, muzzle.rotation);
bulletInstance.GetComponent<Rigidbody>().AddForce(bulletInstance.transform.forward * bulletPower);
Destroy(bulletInstance, 5f);
}
}
このrayの部分をカメラ目線ではなく、プレイヤーからの三人称視点からにできないか考えていく。
using UnityEngine;
using System.Collections;
public class AddForceBullet2 : MonoBehaviour
{
// 弾のゲームオブジェクト
[SerializeField]
private GameObject bulletPrefab;
// 銃口
[SerializeField]
private Transform muzzle;
// 弾を飛ばす力
[SerializeField]
private float bulletPower = 1000f;
private Vector3 force;
void Update()
{
if (Input.GetButtonDown("Fire1"))
{
Vector3 screenPos = Input.mousePosition; //タップ位置のスクリーン座標
Vector3 worldPos = Camera.main.ScreenToWorldPoint(screenPos);//ワールド座標
GetAim(worldPos, muzzle.position);
Shot();
Debug.Log("screenPos" + screenPos);
Debug.Log("worldPos"+worldPos);
Debug.Log("muzzle.position" + muzzle.position);
}
//タップ位置にはZ座標が含まれていない為、透視投影視のカメラでは奥行きが特定出来ない点に注意
/*
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
transform.rotation = Quaternion.LookRotation(ray.direction);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 1f, LayerMask.GetMask("Gun")))
{
Cursor.visible = false;
}
else
{
Cursor.visible = true;
}
// マウスの左クリックで撃つ
if (Input.GetButtonDown("Fire1"))
{
Shot();
}
*/
}
public void GetAim(Vector2 p1, Vector2 p2)
{
float dx = p2.x - p1.x;
float dy = p2.y - p1.y;
force = new Vector3(0, dy/dx,0);//タンジェント
//float rad = Mathf.Atan2(dy, dx); //Tan が y/x になる角度をラジアンで返す
//return rad * Mathf.Rad2Deg;//Rad2Degでラジアンから度数に変換
}
// 敵を撃つ
public void Shot()
{
var bulletInstance = Instantiate<GameObject>(bulletPrefab, muzzle.position, muzzle.rotation);
//bulletInstance.GetComponent<Rigidbody>().AddForce(bulletInstance.transform.forward * bulletPower);
bulletInstance.GetComponent<Rigidbody>().AddForce((bulletInstance.transform.forward + force) * bulletPower);
Debug.Log(force);
Destroy(bulletInstance, 5f);
}
}
一旦rayは用いず、座標の相互関係で、transform.forwardにタンジェントを足すかたちに落ち着いたが、Vector3 worldPos = Camera.main.ScreenToWorldPoint(screenPos);がうまく反映されず、screenPosが変更されても毎回同じ値になってしまう。
Input.mousePositionはz座標を持っていないのでそのままクリックするとMainCameraの座標をとってきてしまっていた。カメラに誤認識されないようにscreenPos.z = 2.0f;を仮で入れて反応を見た。
ボールのショットがクリック位置により高さ変更されている。ただ、上下のクリック認識で高さの変更を行いたかったのに左右の認識の方が高さを出すのにより有効になっているのが問題。
GetAim(muzzle.position, worldPos);の中身の入れ替えとx座標を絶対値でマイナスにならないように設定などしていたがx座標そのものを認識させる必要がないことに気づき消去した。
最終的に下記かたちとなった。
public void GetAim(Vector2 p1, Vector2 p2)
{
//float dx = Mathf.Abs(p2.x - p1.x);
float dy = p2.y - p1.y;
//force = new Vector3(0, dy/dx,0);//タンジェント
force = new Vector3(0, dy, 0);//タンジェント
//float rad = Mathf.Atan2(dy, dx); //Tan が y/x になる角度をラジアンで返す
//return rad * Mathf.Rad2Deg;//Rad2Degでラジアンから度数に変換
}
// 敵を撃つ
public void Shot()
{
var bulletInstance = Instantiate<GameObject>(bulletPrefab, muzzle.position, muzzle.rotation);
//bulletInstance.GetComponent<Rigidbody>().AddForce(bulletInstance.transform.forward * bulletPower);
bulletInstance.GetComponent<Rigidbody>().AddForce((bulletInstance.transform.forward + force) * bulletPower);
Debug.Log(force);
Destroy(bulletInstance, 5f);
}
次はenemyaiに自動追尾させていく。