6 - プレイヤーのカメラワーク
このセクションプレイヤーを追従するCameraWork
スクリプトを作成する方法を説明します。
このセクションはネットワーキングとは関係がないため、簡潔に説明します。
CameraWorkスクリプトを作成
CameraWork
という名前の新しいC#スクリプトを作成します。CameraWork
の内容を以下のように置換します。
C#
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="CameraWork.cs" company="Exit Games GmbH">
// Part of: Photon Unity Networking Demos
// </copyright>
// <summary>
// Used in PUN Basics Tutorial to deal with the Camera work to follow the player
// </summary>
// <author>developer@exitgames.com</author>
// --------------------------------------------------------------------------------------------------------------------
using UnityEngine;
namespace Photon.Pun.Demo.PunBasics
{
/// <summary>
/// Camera work. Follow a target
/// </summary>
public class CameraWork : MonoBehaviour
{
#region Private Fields
[Tooltip("The distance in the local x-z plane to the target")]
[SerializeField]
private float distance = 7.0f;
[Tooltip("The height we want the camera to be above the target")]
[SerializeField]
private float height = 3.0f;
[Tooltip("Allow the camera to be offseted vertically from the target, for example giving more view of the sceneray and less ground.")]
[SerializeField]
private Vector3 centerOffset = Vector3.zero;
[Tooltip("Set this as false if a component of a prefab being instanciated by Photon Network, and manually call OnStartFollowing() when and if needed.")]
[SerializeField]
private bool followOnStart = false;
[Tooltip("The Smoothing for the camera to follow the target")]
[SerializeField]
private float smoothSpeed = 0.125f;
// cached transform of the target
Transform cameraTransform;
// maintain a flag internally to reconnect if target is lost or camera is switched
bool isFollowing;
// Cache for camera offset
Vector3 cameraOffset = Vector3.zero;
#endregion
#region MonoBehaviour Callbacks
/// <summary>
/// MonoBehaviour method called on GameObject by Unity during initialization phase
/// </summary>
void Start()
{
// Start following the target if wanted.
if (followOnStart)
{
OnStartFollowing();
}
}
void LateUpdate()
{
// The transform target may not destroy on level load,
// so we need to cover corner cases where the Main Camera is different everytime we load a new scene, and reconnect when that happens
if (cameraTransform == null && isFollowing)
{
OnStartFollowing();
}
// only follow is explicitly declared
if (isFollowing) {
Follow ();
}
}
#endregion
#region Public Methods
/// <summary>
/// Raises the start following event.
/// Use this when you don't know at the time of editing what to follow, typically instances managed by the photon network.
/// </summary>
public void OnStartFollowing()
{
cameraTransform = Camera.main.transform;
isFollowing = true;
// we don't smooth anything, we go straight to the right camera shot
Cut();
}
#endregion
#region Private Methods
/// <summary>
/// Follow the target smoothly
/// </summary>
void Follow()
{
cameraOffset.z = -distance;
cameraOffset.y = height;
cameraTransform.position = Vector3.Lerp(cameraTransform.position, this.transform.position +this.transform.TransformVector(cameraOffset), smoothSpeed*Time.deltaTime);
cameraTransform.LookAt(this.transform.position + centerOffset);
}
void Cut()
{
cameraOffset.z = -distance;
cameraOffset.y = height;
cameraTransform.position = this.transform.position + this.transform.TransformVector(cameraOffset);
cameraTransform.LookAt(this.transform.position + centerOffset);
}
#endregion
}
}
- スクリプト
CameraWork
を保存します。
The logic behind following the player is simple. We compute the desired camera position with added offset to fall behind using the Distance
and above using the Height
. Then it uses Lerping
for smoothing out the movement to catch up with the desired position and finally, a simple LookAt
for the camera to always point at the Player.
Aside the Camera work itself, something important is also set up; the ability to control when the behaviour should actively follow the player.
And this is important to understand: When would we want to have the camera to follow the player?
いつもいつもプレイヤーを追従しているとどうなるのか考えてみましょう。
プレイヤーが多くいるルームに接続すると、相手のプレイヤーインスタンスのCameraWork
スクリプトが、自分のプレイヤーを写すため「メインカメラ」を制御しようとぶつかり合います。
このような事態は避け、コンピューターの前にいるユーザーを表すローカルプレイヤーのみを追従すべきです。
1つのカメラに対して複数のプレイヤーインスタンスが存在する場合の問題を把握できたので、それを防ぐ方法を以下で説明します。
- ローカルプレイヤーにのみ
CameraWork
スクリプトを添付します。 - 追従するプレイヤーがローカルかどうかに応じてオンとオフを切り替え、
CameraWork
の動作を制御します。 CameraWork
をカメラに取り付け、シーンの中にローカルプレイヤーインスタンスがある場合は注意して、そのプレイヤーのみを追従するようにします。
他にも方法はありますが、これらの3つの方法の中から選ぶとしたら2つ目のオプションをお勧めします。
3つの方法に大差はありませんが、2つ目のオプションはコーディングの量が最も少なく非常に高い柔軟性があります。
- フィールド
followOnStart
を公開しましたので、非ネットワークされた環境で使用する場合trueに設定してください。例:テストシーンや、まったく異なるシナリオ - ネットワークベースのゲームで動作する場合、プレイヤーがローカルであると検出した場合にはパブリックメソッド
OnStartFollowing()
を呼び出します。
これは作成されたスクリプトPlayerManager
で実行されます。このスクリプトについてはプレイヤーネットワーキングの章で説明します。
前に戻る.
Back to top