最近マリオオデッセイ、プレイしました。
私がプレイしてて楽しかったのは、スナップショットモードを使って自由な構図でスクショが取れる部分だ。
現実世界でいう旅行先で写真を撮るような感覚が体験できる。オデッセイワールド堪能。
今回は一時停止中でもカメラを自由に動かせるようなのをつくってみる。
※unity version 2017.2.1
カメラを自由に動かす
既にあるみたいですよ...
baba-s.hatenablog.com
要点
- Time.unscaledDeltaTimeを使用
docs.unity3d.com
以下、私の場合
手始めに、被写体を中心としてマウスのドラッグの方向にカメラが動くようなものをつくった。
目指してた動きはこれなんだけど、実際に動かしてみると操作しづらい...
そもそも、ジョイスティック操作に最適化された操作方法をそれっぽくマウス操作に移植させたようなものだから、コレジャナイ感は当たり前だった。
なので、unityのシーンビューのカメラ操作を目指す。
既に...
既に記事がありました...
qiita.com
有り難く参考にさせて頂いた結果、簡単にそれっぽい感じになった。
その他
ズームさせたり。
カメラをローカルのz軸で回転させたり。
ロゴの位置を変えたり。
一時停止させてみたり。心なしか被写体も嬉しそうだ。
ここで燃え尽きる
それっぽくなったので、ここらで終わりとする。
肝心なスクショ機能は、実装にいたらず。
調べた結果を紹介するだけでとどめておく。
d.hatena.ne.jp
teratail.com
遊んでみた
ダメージ受けた時。
たまたま、新しい公式モデルがでてたので、試しに。
ロゴを配置すると画面が引き締まる気がする。
心なしか、通常時の顔でもアイドルの方が凛々しい。
カメラの制御はこちらで。Time.unscaledDeltaTimeを使っているのは、一時停止中でもカメラを操作を操作できるように。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(Camera))]
public class CameraController : MonoBehaviour {
[SerializeField] Transform targetTrans;
[SerializeField, Range(0.3f, 5)] float moveSpeed = 0.5f;
[SerializeField, Range(0.3f, 5)] float rotateSpeed = 0.5f;
Camera camera;
Vector3 initPos;
float initViewingAngle;
void Start () {
camera = GetComponent<Camera>();
initPos = transform.position;
initViewingAngle = camera.fieldOfView;
}
public void Rotate(Vector2 angle) {
transform.RotateAround(transform.position, transform.right, angle.x * rotateSpeed);
transform.RotateAround(transform.position, Vector3.up, angle.y * rotateSpeed);
}
public void RotateOnZAxis(float angle) {
transform.RotateAround(transform.position, transform.forward, angle);
}
public void Translate(Vector3 movement) {
transform.Translate(movement * Time.unscaledDeltaTime * moveSpeed);
}
public void Translate(float amount) {
transform.Translate(transform.forward * amount * Time.unscaledDeltaTime * moveSpeed);
}
public void Zoom(float amount) {
camera.fieldOfView = amount;
}
public void Reset() {
transform.position = initPos;
transform.rotation = Quaternion.Euler(0, 0, 0);
camera.fieldOfView = initViewingAngle;
}
}
入力部分はこちら。Playerという名前は変えた方がよさそうだ。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour {
[SerializeField] CameraController cameraController;
[SerializeField] Canvas controlCanvas;
Vector3 tapPos = Vector3.zero;
void Update () {
UpdateMouseState();
if (Input.GetKeyDown(KeyCode.Z)) {
controlCanvas.enabled = !controlCanvas.enabled;
}
if (Input.GetKeyDown(KeyCode.Q)) {
Time.timeScale = Time.timeScale == 1 ? 0 : 1;
}
}
void UpdateMouseState() {
if (Input.GetMouseButtonDown(2)) {
tapPos = Input.mousePosition;
}
MouseDrag(Input.mousePosition);
}
void MouseDrag(Vector3 mousePos) {
Vector3 diff = mousePos - tapPos;
if (Input.GetMouseButton(2))
cameraController.Translate(-diff);
else if (Input.GetMouseButton(1))
cameraController.Rotate(new Vector2(-diff.y, diff.x));
tapPos = mousePos;
}
}
CameraController.csはカメラにアタッチした。TargetTransは被写体のTransform。今回は中央の3Dモデルをセットしている。
Player.csは空のオブジェクトにアタッチした。
ライセンス表記
公式モデルを使用したので。
© Unity Technologies Japan/UCL