【unity】プレイヤーのカメラ追従とマウスでの移動

公開日: 2015/10/06 unity

2Dトップビューゲームのプレイヤーのカメラ追従とマウスでの移動を考えてますが色々と悩む
Character Controller(キャラクターコントローラー)という選択肢がある訳ですが、希望の挙動を得られるのかわからないCharacter Controllerも勉強しつつ、自力での実装も試みてみます


理想の挙動


  • プレイヤーキャラクターをカメラ追従でキャラクターは基本中央表示
  • マウスホイールでのズームイン、ズームアウトを可能にする
  • マップの切れ目は見せない、マップ端に近づいたらカメラ追従の切り替え
  • プレイヤーキャラクターはマウスポインタで移動操作
  • ゲーム画面中央付近(プレイヤー付近)ではプレイヤーキャラクターを停止させ動かさない
  • マウスポインタがゲーム画面外に出た場合もプレイヤーキャラクターを停止させ動かさない

プレイヤーにカメラを追従させる

とりあえずカメラ追従ですが、これは過去にも書いた事がありすぐできました
色々な方が紹介して下さっていて沢山サンプルがありますね

プレイヤーのワールド座標にカメラの座標を合わせるだけで簡単には実装できます
ゲーム中、プレイヤーが存在しない可能性があるので一応Updateで確認処理していますが割合
using UnityEngine;
using System.Collections;

public class Camera_Script : MonoBehaviour {
public GameObject player;
void Start () {
player = GameObject.Find("player"); 
 }
void Update(){
transform.position = new Vector3(player.transform.position.x,player.transform.position.y,任意のZ値);
}
}


マウスホイールでのズームイン・アウト

これにマウスホイールでのズームイン・アウトを追加します
マウスホイールが操作されたら合わせてZ値を変更すればいいのですね
using UnityEngine;
using System.Collections;

public class Camera_Script : MonoBehaviour {
public GameObject player;
public float size;
void Start () {
player = GameObject.Find("player"); 
 }
void Update(){
float fWheel = Input.GetAxis("Mouse ScrollWheel"); 
transform.Translate(0, 0,(fWheel * 5));
size = transform.position.z;
transform.position = new Vector3(player.transform.position.x,player.transform.position.y,size);
}
}

マウスホイールでのズームイン・アウトに制限を設けないといけません
デバックでカメラのz軸を確認したところ作っているゲームでは-4~-11あたりが良さそうなので・・
using UnityEngine;
using System.Collections;

public class Camera_Script : MonoBehaviour {
public GameObject player;
public float size;
void Start () {
player = GameObject.Find("player"); 
 }
void Update(){
float fWheel = Input.GetAxis("Mouse ScrollWheel"); 
transform.Translate(0, 0,(fWheel * 4));
size = transform.position.z;
  if(size <= -11){
   size = -11;
  }
  if(size >= -4){
   size = -4;
  }
transform.position = new Vector3(player.transform.position.x,player.transform.position.y,size);
}
}


マップの切れ目を表示しないようにする

マップの切れ目を表示しないようにするにはカメラの座標に限界値を設定して到達したらプレイヤー追従から切り替える必要がありますね
これはx軸とy軸を別々な処理で単にそれ以上動かない様にするだけでしょう
ただ、今回はズームイン・アウトを考慮しなければならず、まだ書いてません・・
ズームアウト時に軸を移動する(戻す)のは想像するに気持ち悪いですし、その分のマップ追加も本末転倒です
どうしたものか・・

プレイヤーをマウスポインタで移動操作

マウスでプレイヤーを操作するのはマウスポインタの座標をInput.mousePositionで取得すればおkなのですね
https://gist.github.com/Buravo46/8367810より拝借
スクリプトはプレイヤーキャラクターにアタッチするものとします

このままでは超スピードでプレイヤーが移動してしまうので
using UnityEngine;
using System.Collections;

public class MouseSynchronizeObjectScript : MonoBehaviour {

 // 位置座標
 private Vector3 position;
 // スクリーン座標をワールド座標に変換した位置座標
 private Vector3 screenToWorldPointPosition;
 private Vector3 direction;
 public float speed;
 void Start () {
  
 }
 
 // Update is called once per frame
 void Update () {
  // Vector3でマウス位置座標を取得する
  position = Input.mousePosition;
  // Z軸修正
  position.z = 10f;
  // マウス位置座標をスクリーン座標からワールド座標に変換する
  screenToWorldPointPosition = Camera.main.ScreenToWorldPoint (position);
  direction = screenToWorldPointPosition - transform.position;
      
  rigidbody2D.velocity = direction * speed;
    
 }
}

ここからプレイヤーキャラクター付近にマウスポインタがある状態とゲーム画面外にマウスポインタが出た場合にはプレイヤーキャラクターを動かさない為の方法を考える

紹介されていたコードにあるdirectionはプレイヤーを中心とした座標になるので-1~1の範囲の場合は0にする
using UnityEngine;
using System.Collections;

public class MouseSynchronizeObjectScript : MonoBehaviour {

 // 位置座標
 private Vector3 position;
 // スクリーン座標をワールド座標に変換した位置座標
 private Vector3 screenToWorldPointPosition;
 private Vector3 direction;
 public float speed;
 void Start () {
  
 }
 
 // Update is called once per frame
 void Update () {
  // Vector3でマウス位置座標を取得する
  position = Input.mousePosition;
  // Z軸修正
  position.z = 10f;
  // マウス位置座標をスクリーン座標からワールド座標に変換する
  screenToWorldPointPosition = Camera.main.ScreenToWorldPoint (position);
  direction = screenToWorldPointPosition - transform.position;
  if (direction.x <= 1 && direction.x >= 1) {
   direction.x = 0;
    }
  if (direction.y <= 1 && direction.y <= 1) {
   direction.y = 0;
  }
  
  rigidbody2D.velocity = direction * speed;
    
 }
}

で、ゲーム画面外にマウスポインタが出た場合ですがここで困惑してます
スクリーン座標は左下が0,0なのでゲーム画面の左もしくは下にマウスポインタがある場合は簡単なのですが、右・上に関してはプレイ環境で数値が変わってしまうのでは・・
と思ったら、画面サイズを取得すればとりあえずできそうです
using UnityEngine;
using System.Collections;

public class MouseSynchronizeObjectScript : MonoBehaviour {

 // 位置座標
 private Vector3 position;
 // スクリーン座標をワールド座標に変換した位置座標
 private Vector3 screenToWorldPointPosition;
 private Vector3 direction;
 public float speed;
 int width = Screen.width;
 int height = Screen.height;
 void Start () {
  
 }
 
 // Update is called once per frame
 void Update () {
  // Vector3でマウス位置座標を取得する
  position = Input.mousePosition;
  // Z軸修正
  position.z = 10f;
  // マウス位置座標をスクリーン座標からワールド座標に変換する
  screenToWorldPointPosition = Camera.main.ScreenToWorldPoint (position);
  direction = screenToWorldPointPosition - transform.position;
  if (direction.x <= 1 && direction.x >= 1) {
   direction.x = 0;
    }
  if (direction.y <= 1 && direction.y <= 1) {
   direction.y = 0;
  }

  if (position.x >= width || position.x <= 0 || position.y >= height || position.y <= 0) {
   direction.x = 0;
   direction.y = 0;
  }
  
  rigidbody2D.velocity = direction * speed;
    
 }
}

マウスポインタが画面外に出てもキャラクターが動いてしまうのはブラウザゲームで良くありますが、これが結構ストレスの対象なんですよね
なんとかなりそうで良かったです

velocityだと力のかかり方が理想と違うので別の方法を考えなくては・・!
  • ?±??G???g???[?d????u?b?N?}?[?N???A

1 件のコメント :

  1. 2Dトップビューゲームのプレイヤーのカメラ追従とマウスでの移動を考えてますが色々と悩む. Character Controller(キャラクターコントローラー)という選択肢がある訳ですが、希望の挙動を得られるのかわからないCharacter Controllerも ... マウス.blogspot.com

    返信削除