王者荣耀实时对战服务器Photon之PUN创建角色预设(一)

发表于2017-11-18
评论0 2k浏览

本节将指导您如何从头开始创建将并使用Player Prefab,我们将一步一步创建Player Prefab,来完善Photonpun 创建加入房间之后,角色的互动操作。

在没有PUN网络连接的情况下,创建Player Prefab是一种很好的方法,因为可以快速测试,调试和确保所有内容在没有PUN任何网络功能的情况下工作。 然后,您可以逐渐建立和修改每个功能加入到PUN网络中:通常,用户输入创建在角色只能自己去实例化和激活,而不能在其他玩家计算机上激活。 我们将在下面详细介绍。

The Prefab Basics

了解PUN的第一个重要的惯例就是对于通过网络实例化的Prefab,它需要在Resources文件夹中,否则就不可行,这一点非常重要。

Prefabs在资源中的第二个重要的一点是你需要注意他们的名字。您不应该在您的资产资源资源路径下面命名两个Prefab也就是不仅重名,因为Unity将选择它找到的第一个,因此始终确保在您的Project Assets中,资源文件夹路径中没有两个Prefabs,名为相同。

我们将使用Unity提供的免费资源Kyle机器人。它是一个Fbx文件,由3ds MaxMayacinema4d3d软件生成。这个的网格和动画的创建超出了这些软件教程的范围,但是创建自己的角色和动画是至关重要的。这个机器人Kyle.fbx位于 /Assets/Photon Unity Networking/Demos/Shared Assets/

我们在使用Kyle Robot.fbx的一种方法是:

在项目浏览器中,创建一个名为“资源”的文件夹,通常建议您有序放置这些内容,因此可能会有“DemoAnimator_tutorial / Resources /

创建一个新的空白场景,并保存为Kyle Test in / PunBasics_tutorial / Scenes /

将机器人Kyle拖放到场景层次结构上。

将您刚刚在层次结构中创建的GameObject重命名为“MyRobotKyle”

MyRobotKyle拖放到/ PunBasics_tutorial / Resources /

我们现在已经创建了一个基于Kyle Robot Fbx资源的Prefab,我们在Kyle Test的层次结构中有一个实例。 现在我们可以开始使用它了。

CharacterController

我们在层次结构中添加一个CharacterController组件到MyRobotKyle实例。 你可以直接在Prefab上这样做,但是我们需要调整它,所以这样更快。

该组件是Unity提供的非常方便的标准组建,为我们使用Animator生成更快的典型字符,所以让我们利用Unity实现这些功能。

双击我的Kyle机器人使场景视图放大。注意胶囊碰撞对撞机以脚为中心我们实际上需要胶囊对撞机才能正确匹配角色。

CharacterController组件中,将Center.y属性更改为1(其Height属性的一半)。

点击申请按钮保存我们刚才的操作。 这是一个非常重要的一步,因为我们编辑了我的预制Kyle这个实例,但我们希望这些更改是针对每一个实例,而不仅仅是这个,所以我们点击应用。

Animator Setup

Assigning an Animator Controller

Kyle机器人Fbx资源需要由动画控制。 我们不会在本教程中介绍Uniy的动画系统的创建,因此我们提供了一个控制器,位于您的项目资源下,你可以方便的找到并且使用它。

需要将Kyle机器人控制器分配给我们的预制,只需将动画组件的属性控制器设置为指向Kyle机器人

不要忘记,如果您在MyRobotKyle实例”上执行此操作,则需要点击申请Prefab本身来合并这些更改。

Working with the Controller Parameters

动画控制器的关键功能是了解动画参数,这是我们将如何通过脚本控制动画。 在我们的例子中,我们有参数,如速度,方向,跳转。

Unity动画组件的一大特色就是能够根据动画实际移动角色,该功能称为“根运动”,并且在动画组件上有一个属性应用根运动,默认情况下为true.

实际上,要让角色走路,我们只需要将速度动画参数设置为正值,它将开始播放行走动画时候并向前移动。 

Animator Manager Script

我们创建一个新脚本,我们将获取用户的输入的内容。 

1.在DemoAnimator / tutorial / Scripts / Script中创建一个名为PlayerAnimatorManager的新c#脚本,

2.将此脚本附加到MyRobotKyle的Prefab 

3.使用NameSpace Com.MyCompany.MyGame命名空间,如下所示

using UnityEngine;

using System.Collections;

namespace Com.MyCompany.MyGame

    public class PlayerAnimatorManager : MonoBehaviour 

    {

        #region MONOBEHAVIOUR MESSAGES

        // Use this for initialization

        void Start() 

        {

        }

        // Update is called once per frame

        void Update() 

        {

        }

        #endregion

    }

4.保存脚本。

Animator Manager: Speed Control

我们需要做的的第一件事就是获取动画组件,以便我们可以控制它。

确保您正在编辑Script PlayerAnimatorManager

创建一个类型为Animator的私有变量动画

Start()方法中将动画组件存储在此变量中。

private Animator animator;

// Use this for initialization

void Start() 

    animator = GetComponent<Animator>();

    if (!animator)

    {

        Debug.LogError("PlayerAnimatorManager is Missing Animator Component",this);

    }

请注意,由于我们需要一个动画组件,如果我们没有得到一个,我们会记录一个错误,使其不会被忽视,并被开发人员直接处理,做好为空的判断。

现在我们来听用户输入并控制速度动画参数。 然后保存脚本PlayerAnimatorManager

// Update is called once per frame

void Update() 

    if (!animator)

    {

        return;

    }

    float h = Input.GetAxis("Horizontal");

    float v = Input.GetAxis("Vertical");

    if (v < 0)

    {

        v = 0;

    }

    animator.SetFloat("Speed", h * h + v * v);

保存脚本

我们来看看这个脚本实现什么功能:

由于我们的游戏不允许后退,我们确保v小于0.用户按下向下键或's'键,我们不允许这样做,并将该值强制为0

您还会注意到我们已经对两个输入进行了平方,为什么? 所以它永远是一个正数的绝对价值。 这里很好的微妙的招数。 你也可以使用Mathf.Abs(),这样可以正常工作。

我们还添加了两个输入来控制速度,所以当刚刚向左按右边的输入时,我们仍然会转过一些速度。

所有这一切对于我们的角色设计当然是非常具体的,根据你的游戏逻辑,你可能希望角色转身,或者有能力向后退,所以控制动画参数总是非常具体的游戏。

Test, test, 1 2 3...

让我们验证我们到目前为止做了什么。确保您打开测试场景。目前,在这个场景中,我们只有一台摄像头和MyRobotKyle实例,场景中缺少机器人站立的地面,如果你现在跑跑了MyRobotKyle机器人会掉下来的场景。此外,我们没有在现场添加照明,我们想测试和验证我们的角色和脚本是否正常工作。

向场景添加立方体。因为立方体在默认情况下是一个盒子碰撞器,所以我们很乐意使用它,就像现在一样。

将其定位在0-0.5,0,因为立方体的高度是1.我们希望立方体的顶面是地板。

将立方体缩放为30,1,30,以便我们有空间

选择相机并将其移开以获得良好的视野。

最后一步,移动MyRobotKyle 0.1y,否则在开始就产生了碰撞,角色就会穿过地板,所以要提高一点。

玩场景,按向上箭头键或'a',角色走路!您可以进行测试。

这是好的,但仍然有很多工作在我们之前,比如相机需要跟随,我们不能转身...

Animator Manager Script: Direction Control

控制旋转将稍微复杂一些我们不要让我们的角色突然旋转,因为我们按左右键,我们需要温柔平滑的旋转。可以使用一些阻尼来设置动画参数

确保您正在编辑Script PlayerAnimatorManager脚本

PRIVATE PROPERTIES”区域上方的脚本的新区域“PUBLIC PROPERTIES”中创建一个公共float变量DirectionDampTime

//#region PUBLIC PROPERTIES

public float DirectionDampTime = .25f;

//#endregion

Update()函数的末尾,添加:

animator.SetFloat("Direction", h, DirectionDampTime, Time.deltaTime);

所以我们马上注意到animator.SetFloat()有不同的参数。我们用于控制速度的是简单的,但是对于这个参数,需要两个参数,一个是阻尼时间,一个是deltaTime。阻尼时间是:达到期望值需要多长时间,但是deltaTime?它基本上允许您编写与帧速率无关的代码,因为Update()取决于帧速率,我们需要通过使用deltaTime来实现,将能够充分利用许多Unity功能,当涉及到动画和一致的时间控制值时。

保存脚本PlayerAnimatorManager

玩你的场景,并使用所有的箭头,看看你的角色走路和转身有多好。

测试DirectionDampTime的效果:把它放在一个例子,然后5,看到长达到达到最大转弯能力。您会看到转向半径随DirectionDampTime增加。

Animator Manager Script: Jumping

与跳跃,我们需要更多的工作,因为两个因素。 一个,我们不希望玩家在不运行跳转,二,我们不希望跳跃循环。

确保您正在编辑Script PlayerAnimatorManager

在我们Update()方法中的用户输入之前插入这个。

// deal with Jumping

AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0);          

// only allow jumping if we are running.

if (stateInfo.IsName("Base Layer.Run"))

    // When using trigger parameter

    if (Input.GetButtonDown("Fire2")) 

    {

        animator.SetTrigger("Jump");

    }                

保存脚本PlayerAnimatorManager

测试。 开始运行并按alt”键,Kyle机器人应该跳。

好的,所以了解的第一件事是我们如何知道动画状态是否运行,我们使用stateInfo.IsName(“Base Layer.Run”)这样做。 我们只是询问动画状态的当前活动状态是否运行。 我们必须追加基础层,因为运行状态是在基础层。

如果我们处于运行状态,那么我们听Fire2输入并提高跳转触发是必要的。

所以,这是完整的PlayerAnimatorManager脚本:

using UnityEngine;

using System.Collections;

namespace Com.MyCompany.MyGame

    public class PlayerAnimatorManager : MonoBehaviour 

    {

        #region PRIVATE PROPERTIES

        public float DirectionDampTime = .25f;

        #endregion

        #region PRIVATE PROPERTIES

        private Animator animator;

        #endregion

        #region MONOBEHAVIOUR MESSAGES

        // Use this for initialization

        void Start() 

        {

            animator = GetComponent<Animator>();

            if (!animator)

            {

                Debug.LogError("PlayerAnimatorManager is Missing Animator Component",this);

            }

        }

        // Update is called once per frame

        void Update() 

        {

            if (!animator)

            {

                return;

            }

            // deal with Jumping

            AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0);    

            // only allow jumping if we are running.

            if (stateInfo.IsName("Base Layer.Run"))

            {

                // When using trigger parameter

                if (Input.GetButtonDown("Fire2")) 

                {

                    animator.SetTrigger("Jump");

                }                    

            }

            float h = Input.GetAxis("Horizontal");

            float v = Input.GetAxis("Vertical");

            if (v < 0)

            {

                v = 0;

            }

            animator.SetFloat("Speed", h * h + v * v);

            animator.SetFloat("Direction", h, DirectionDampTime, Time.deltaTime);

        }

        #endregion

    }


不管你有关于Photon产品的问题或者是Photon价格问题或者Photon教程方面的问题或者其他问题都可以联系我们给我我们留言,我们真诚的为您服务。关注我们公众号PhotonServer获取等多新鲜资讯。


关注我们公众号PhotonServer 获取最新教程资源。

王者荣耀实时对战服务器Photon之Pun应用系列文章 如果你喜欢请关注我公众号,并推荐给你你的小伙伴,谢谢。

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引