Photon Unity Networking基础教程 6 - Player Camera Work

这部分将会知道你创建CameraWork脚本,再你玩游戏的时候让相机跟随你的角色。这个脚本和网络没什么关系,所以简短介绍。

主要内容

  • 创建CameraWork脚本

创建CameraWork脚本

  1. 新建一个C#脚本,命名为CameraWork

  2. 把CameraWork的内容替换成下面的代码

     using UnityEngine;
     using System.Collections;
     
     namespace Com.MyCompany.MyGame
     {
         /// <summary>
         /// Camera work. Follow a target
         /// </summary>
         public class CameraWork : MonoBehaviour
         {
             #region Public Properties
     
             [Tooltip("The distance in the local x-z plane to the target")]
             public float distance = 7.0f;
     
             [Tooltip("The height we want the camera to be above the target")]
             public float height = 3.0f;
     
             [Tooltip("The Smooth time lag for the height of the camera.")]
             public float heightSmoothLag = 0.3f;
     
             [Tooltip("Allow the camera to be offseted vertically from the target, for example giving more view of the sceneray and less ground.")]
             public 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.")]
             public bool followOnStart = false;
     
             #endregion
     
             #region Private Properties
             // cached transform of the target
             Transform cameraTransform;
     
             // maintain a flag internally to reconnect if target is lost or camera is switched
             bool isFollowing;
             // Represents the current velocity, this value is modified by SmoothDamp() every time you call it.
             private float heightVelocity = 0.0f;
             // Represents the position we are trying to reach using SmoothDamp()
             private float targetHeight = 100000.0f;
             #endregion
     
             #region MonoBehaviour Messages
             /// <summary>
             /// MonoBehaviour method called on GameObject by Unity during initialization phase
             /// </summary>
             void Start()
             {
                 // Start following the target if wanted.
                 if (followOnStart)
                 {
                     OnStartFollowing();
                 }
             }
     
             /// <summary>
             /// MonoBehaviour method called after all Update functions have been called. This is useful to order script execution. For example a follow camera should always be implemented in LateUpdate because it tracks objects that might have moved inside Update.
             /// </summary>
             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)
                 {
                     Apply();
                 }
             }
             #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 Apply()
             {
                 Vector3 targetCenter = transform.position + centerOffset;
     
                 // Calculate the current & target rotation angles
                 float originalTargetAngle = transform.eulerAngles.y;
                 float currentAngle = cameraTransform.eulerAngles.y;
     
                 // Adjust real target angle when camera is locked
                 float targetAngle = originalTargetAngle;
                 currentAngle = targetAngle;
                 targetHeight = targetCenter.y + height;
     
                 // Damp the height
                 float currentHeight = cameraTransform.position.y;
                 currentHeight = Mathf.SmoothDamp(currentHeight, targetHeight, ref heightVelocity, heightSmoothLag);
     
                 // Convert the angle into a rotation, by which we then reposition the camera
                 Quaternion currentRotation = Quaternion.Euler(0, currentAngle, 0);
     
                 // Set the position of the camera on the x-z plane to:
                 // distance meters behind the target
                 cameraTransform.position = targetCenter;
                 cameraTransform.position += currentRotation * Vector3.back * distance;
     
                 // Set the height of the camera
                 cameraTransform.position = new Vector3(cameraTransform.position.x, currentHeight, cameraTransform.position.z);
     
                 // Always look at the target    
                 SetUpRotation(targetCenter);
             }
     
             /// <summary>
             /// Directly position the camera to a the specified Target and center.
             /// </summary>
             void Cut()
             {
                 float oldHeightSmooth = heightSmoothLag;
                 heightSmoothLag = 0.001f;        
                 Apply();        
                 heightSmoothLag = oldHeightSmooth;
             }
     
             /// <summary>
             /// Sets up the rotation of the camera to always be behind the target
             /// </summary>
             /// <param name="centerPos">Center position.</param>
             void SetUpRotation(Vector3 centerPos)
             {
                 Vector3 cameraPos = cameraTransform.position;
                 Vector3 offsetToCenter = centerPos - cameraPos;        
     
                 // Generate base rotation only around y-axis
                 Quaternion yRotation = Quaternion.LookRotation(new Vector3(offsetToCenter.x, 0, offsetToCenter.z));        
     
                 Vector3 relativeOffset = Vector3.forward * distance + Vector3.down * height;
                 cameraTransform.rotation = yRotation * Quaternion.LookRotation(relativeOffset);        
     
             }
             #endregion
         }
     }
    
  3. 保存脚本

如果你刚刚开始与实时3d,向量和四元数学,那么跟随玩家角色的数学是复杂的。所以我尝试在本教程中解释这一点。但是如果你好奇,想学习,不要犹豫与我们联系,我们会尽最大努力解释清楚。

然而,这个脚本不仅仅是疯狂的数学,设置也是重要的,以及控制何时应该主动跟随玩家的能力。理解这点很重要:我们为什么要控制什么时候跟随玩家。

通常,让我们想象如果总是跟随玩家会发生什么。当你连接到一个充满玩家的房间,其他玩家的每个CameraWork脚本为了一直看着自己的角色会相互打架...我们不想要这种,我们只想跟随本地玩家角色,它代表的是计算机后面的用户。

一旦我们定义了这个问题,我们只有一个摄像机,但有多个Player实例,我们可以很容易找到几种方法。

  • 仅在本地玩家上附加CameraWork脚本。
  • 通过关闭和打开来控制CameraWork行为,具体取决于要关注的Player是否是本地玩家。
  • 让CameraWork连接到相机,并注意当场景中有一个本地玩家实例时只跟随那个。

这3个选项并不详尽,可以找到更多的方法,但在这3个选项中,我们将任意选择第二个。上面的选项没有更好或更坏,但是这是一个可能需要最少的编码和最灵活的...“有趣...”我听到你说:)

  • 我们暴露了一个公共属性followOnStart,如果我们想在非联网环境中使用它,我们可以设置为true,例如在我们的测试场景中,或者在完全不同的场景

  • 当在我们的网络游戏中运行时,当我们检测到Player是本地玩家时,我们将调用公共方法OnStartFollowing()。这将在PlayerManager脚本中完成,该脚本PlayerManager在“Player Prefab Networking”一章中创建和解释。

原文

http://doc.photonengine.com/en-us/pun/current/tutorials/pun-basics-tutorial/player-camera-work

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,527评论 5 470
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,314评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,535评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,006评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,961评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,220评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,664评论 3 392
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,351评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,481评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,397评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,443评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,123评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,713评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,801评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,010评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,494评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,075评论 2 341

推荐阅读更多精彩内容