前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >PUN ☀️六、机器人基础设置:运动、相机、攻击与生命值

PUN ☀️六、机器人基础设置:运动、相机、攻击与生命值

作者头像
星河造梦坊官方
发布于 2024-08-15 13:09:35
发布于 2024-08-15 13:09:35
7900
代码可运行
举报
运行总次数:0
代码可运行

🟥 效果展示

首先,将PUN设为离线模式,先来进行本地测试。等发布时,再取消勾选改为联网模式。

为什么设置,可参考:传送门

🟧 机器人运动

Robot Kyle 从Assets拖到层级面板,进行如下配置:

1️⃣ 状态机及状态机控制

a、指定机器人状态机:Kyle Robot

b、挂载如下代码:

该代码负责控制机器人运动,WAD运动,跑起来后右键跳跃。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
using Photon.Pun;
using UnityEngine;
 
public class PlayerAnimatorManager : MonoBehaviourPun
{
    #region Private Fields
 
    [SerializeField]
    float directionDampTime = 0.25f;
    Animator animator;
 
    #endregion
 
 
    #region Mono CallBacks
 
    void Start()
    {
        animator = GetComponent<Animator>();
    }
 
    void Update()
    {
        //教程参考:https://skode.blog.csdn.net/article/details/106356112
        if (PhotonNetwork.IsConnected == true && photonView.IsMine == false)
            return;
 
        AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0);
 
        // 只有在我们跑步的时,按下右键才允许跳跃。
        if (stateInfo.IsName("Base Layer.Run") && Input.GetButtonDown("Fire2"))
            animator.SetTrigger("Jump");
 
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical") < 0 ? 0 : Input.GetAxis("Vertical");
 
        animator.SetFloat("Speed", h * h + v * v);
        animator.SetFloat("Direction", h, directionDampTime, Time.deltaTime);
    }
 
    #endregion
}

2️⃣ 添加角色控制器

为机器人添加 CharacterController,调整Center等,属性如下:

3️⃣ 制作预制体

创建 Resources 文件夹,将Robot Kyle拖到Resources制成预制体。

🟨 相机跟随

为机器人添加如下脚本,勾选 FollwOnStart

该脚本的FollowOnStart,为离线模式,该功能是在离线模式下,让摄像机自动找到人物跟随。在发布时的联网状态下,需取消勾选,自己写代码判断哪个人物是自己的,来跟随。

你的Camera要为 MainCamera

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
using UnityEngine;
 
// Camera work. Follow a target
public class Skode_CameraWork : MonoBehaviour
{
    #region  Fields
 
    [Tooltip("在局部x-z平面到目标的距离")]
    public float distance = 7.0f;
 
    [Tooltip("我们希望相机高于目标的高度")]
    public float height = 3.0f;
 
    [Tooltip("相机高度的平滑时滞")]
    public float heightSmoothLag = 0.3f;
 
    [Tooltip("允许相机垂直于目标,例如,提供更多的景色和较少的地面")]
    public Vector3 centerOffset = Vector3.zero;
 
    [Tooltip("如果预制组件被光子网络改变,则将此设置为false,并在需要时手动调用OnStartFollowing()")]
    public bool followOnStart = false;
 
    // 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.
    float heightVelocity;
 
    // Represents the position we are trying to reach using SmoothDamp()
    float targetHeight = 100000.0f;
 
    #endregion
 
 
    #region Mono Callbacks
 
    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)
            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
}

🟩 攻击系统

1️⃣ 激光射线

在机器人Head下新建如图所示两个cube作为激光射线

2️⃣ 碰撞器设置

只使用一个Collider就好,并作为触发器,避免作为碰撞器将别人碰飞

  • 将右眼激光的Collider移除,左眼Collider拉大包裹住两个cube
  • 勾选Collider的 isTrigger
  • 将带Collider射线的tag设为 beam

3️⃣ 激光控制

机器人添加下方脚本,并将Beams赋值给它

实现:当按下鼠标左键,打开激光。松开左键,关闭激光。

在网络中多人玩,还要考虑: 我按下了鼠标左键,那场景中的各个机器人,怎么判断我是属于谁,你按下鼠标左键我要不要执行程序? if (photonView.IsMine),便实现了此功能。判断这个机器人是不是我的。是的话,执行程序。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
using UnityEngine;
using Photon.Pun;
 
public class PlayerManager : MonoBehaviour
{
    #region Parameters
 
    public GameObject beams;
 
    //当用户开火时,为True
    bool IsFiring;
 
    #endregion
 
 
    #region Mono CallBacks
 
    void Awake()
    {
        beams.SetActive(false);
    }
 
    void Update()
    {
        if (PhotonNetwork.IsConnected == true && photonView.IsMine)
            ProcessInputs();
 
        if (IsFiring != beams.activeSelf)
            beams.SetActive(IsFiring);
    }
 
    #endregion
 
 
    #region Private Methods
 
    void ProcessInputs()
    {
        //鼠标左键
        if (Input.GetButtonDown("Fire1"))
            IsFiring = true;
 
        if (Input.GetButtonUp("Fire1"))
            IsFiring = false;
    }
 
    #endregion
}

4️⃣ 预制体Apply一下

🟦 生命值系统

目标:

当射线击中时,扣0.1血,一直击中,每秒0.1。 当生命值0时,离开房间。

1、GameManager改为单例

2、PlayerManager 更新如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
using UnityEngine;
using Photon.Pun;
 
public class PlayerManager : MonoBehaviourPunCallbacks
{
    #region Parameters
 
    public GameObject beams;
 
    public float Health = 1f;
 
    //当用户开火时,为True
    bool IsFiring;
 
    #endregion
 
 
    #region Mono CallBacks
 
    void Awake()
    {
        beams.SetActive(false);
    }
 
    void Update()
    {
        if (Health <= 0f)
            GameManager.ins.Skode_LeaveRoom();
 
        if (PhotonNetwork.IsConnected == true && photonView.IsMine)
            ProcessInputs();
 
        if (IsFiring != beams.activeSelf)
            beams.SetActive(IsFiring);
    }
    #endregion
 
 
    #region Private Methods
 
    void ProcessInputs()
    {
        //鼠标左键
        if (Input.GetButtonDown("Fire1"))
            IsFiring = true;
 
        if (Input.GetButtonUp("Fire1"))
            IsFiring = false;
    }
 
    void OnTriggerEnter(Collider other)
    {
        if (!photonView.IsMine && !other.CompareTag("beam"))
            return;
 
        Health -= 0.1f;
    }
 
    void OnTriggerStay(Collider other)
    {
        if (!photonView.IsMine && !other.CompareTag("beam"))
            return;
 
        //乘以增量时间,防止因为帧率FPS不同,扣血不同(举例:不乘,每帧执行一次扣血,卡的人比流畅的人扣血少)
        Health -= 0.1f * Time.deltaTime;
    }
    #endregion
}

大家还有什么问题,欢迎在下方留言!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-09-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
PUN ☀️九、玩家网络实例化与昵称显示
原先只有两个人,再加入一个人,会切换到3人的场景。但原先的两个人当前战斗数据会被重置,这是不合理的。
星河造梦坊官方
2024/08/15
790
PUN ☀️九、玩家网络实例化与昵称显示
网络游戏简单化!PUN插件了解一下?(Unity3D)
Photon Unity Networking (PUN)是一种用于多人游戏的Unity软件包。 灵活的匹配可以让玩家进入房间,可以通过网络同步对象。 快速和可靠的通信是通过专用的Photon 服务器完成的,因此客户端连接不需要1对1。
恬静的小魔龙
2022/08/07
3.1K0
网络游戏简单化!PUN插件了解一下?(Unity3D)
PUN☀️七、网络同步:Object Synchronization
-0Fixed:固定的 -0Takeover:可被接管的 -0Request:可被请求接管
星河造梦坊官方
2024/08/15
1230
PUN☀️七、网络同步:Object Synchronization
手把手带你使用Paint in 3D和Photon撸一个在线涂鸦画板
Paint in 3D用于在游戏内和编辑器里绘制所有物体。所有功能已经过深度优化,在WebGL、移动端、VR 以及更多平台用起来都非常好用!
万猫学社
2022/06/14
5740
手把手带你使用Paint in 3D和Photon撸一个在线涂鸦画板
零基础入门 34:摄像机跟随目标
hello,今天来抽出时间给大家更新一发,之前有好多同学和我反馈说特别想要一个收藏贴可以分享如何制作摄像机追随目标,经过大家一而再再而三的催促,今天来给大家分享一下如何实现这个功能。
韩东吉
2018/10/19
7470
零基础入门 34:摄像机跟随目标
Unity的一些基础总结
    这几天重新拾起了自己草草学习的unity技术(不到一周),开始了大胆的模仿原神之路。下面做一些总结。
时光潜流
2022/12/26
1.3K0
Unity的一些基础总结
PUN☀️三、服务器大厅、服务器房间
注意:在连接服务器失败OnDisconnected() 时,显示开始连接和输入名字:
星河造梦坊官方
2024/08/15
1020
PUN☀️三、服务器大厅、服务器房间
Unity动画☀️9. 木头自转、扛起木头、OnTriggerEnter
1️⃣ 导入木头Log,找回丢失的贴图,通过Perfab的Model—Scale Factor调节导入比例—0.3
星河造梦坊官方
2024/08/14
1210
Unity动画☀️9. 木头自转、扛起木头、OnTriggerEnter
官方案例--Survival Shoot(一)
导入Survival Shooter.unitypackage,里面有个完整了,新版本导入的时候,需要简单的修改一下代码;
酱紫安
2021/11/30
4630
官方案例--Survival Shoot(一)
Unity动画☀️11. IK动画—手与木头的匹配
MatchTarget实现从一段时间区域内,一个点到另一个点匹配的过程;IK动画用于直接将手或脚与某点的匹配
星河造梦坊官方
2024/08/14
2150
Unity动画☀️11. IK动画—手与木头的匹配
PUN☀️一、基础配置、搭建大厅程序
你可以直接输入你申请的Appid,点Setup Project;或Skip跳过,选择Project里的PhotonServerSettings,将配置好的Appid填入该位置。
星河造梦坊官方
2024/08/15
1190
PUN☀️一、基础配置、搭建大厅程序
PUN☀️四、服务器大厅建房解析
PlayerNumbering作为PUN实用脚本,挂载到场景中,配合我们写的代码。
星河造梦坊官方
2024/08/15
900
PUN☀️四、服务器大厅建房解析
Unity动画☀️7. 通过MatchTarget匹配跳墙动画、Vector3、获取动画层GetCurrentAnimatorStateInfo(a).IsName(b)
b、Animator.GetCurrentAnimatorStateInfo(a).IsName("b")
星河造梦坊官方
2024/08/14
1100
Unity动画☀️7. 通过MatchTarget匹配跳墙动画、Vector3、获取动画层GetCurrentAnimatorStateInfo(a).IsName(b)
MMORPG游戏开发实战(一)
新建目录工程 关于工程的文件夹创建 代码注释修改 可以百度,这种代码不需要记忆。一大堆,直接用就可以 using System; using System.Collections; using System.IO; using UnityEngine; using UnityEditor; public class ScriptsCreat : UnityEditor.AssetModificationProcessor { public static void OnWillCreateAss
孙寅
2020/06/02
9580
MMORPG游戏开发实战(一)
Unity第三人称视角解决方案
镜头跟随 在实现第三人称时,镜头问题困扰了我一整天,参考了官方的脚本 SmoothFollow,虽然能实现镜头跟在人物身后,但是发现几个问题。 脚本实现太繁琐,有几个属性目前根本就用不到。 人物旋转时不能控制摄像机跟着旋转,也就是说,不能让镜头一直跟在人物身后。 脚本代码如下: public class SmoothFollow : MonoBehaviour { // The target we are following [SerializeField] private Transfo
xferris
2018/06/01
2.6K0
【Unity3D】鼠标射线点击,UI出现在鼠标点击的位置
创建一条射线Ray需要指明射线的起点(origin)和射线的方向(direction)。这两个参数也是Ray的成员变量。注意,射线的方向在设置时如果未单位化,Unity 3D会自动进行单位归一化处理。射线Ray的构造函数为 :
恬静的小魔龙
2020/03/10
5.1K0
【Unity3D开发小游戏】Unity3D零基础一步一步教你制作跑酷类游戏
最近跑酷游戏比较流行,开发教程也很多,但是大部分都是不太详细,这篇文章就带着大家一步一步开发出来一个跑酷类的游戏,教程比较基础,适合大部分Unity开发的初学者。 还有就是,此专栏已经开通收费,里面整合的都是小游戏的开发教程,想要学习Unity开发游戏的,都可以订阅一下。 如果文章出现什么问题,就及时联系我
恬静的小魔龙
2022/08/07
1.9K0
【Unity3D开发小游戏】Unity3D零基础一步一步教你制作跑酷类游戏
unity3d:模型跟随鼠标运动,旋转
立羽
2023/08/24
4241
Unity3d EasyAR开发案例系列教程
这篇文章介绍如何使用EasyAR.unitypackage配置EasyAR ---------- 参考资料 1、EasyAR 初学者入门指南 http://forum.easyar.cn/portal
恬静的小魔龙
2020/03/09
3K0
Unity3d EasyAR开发案例系列教程
Unity-黑暗之魂复刻-角色摄相机
1.使用两个Handle控制MainCamera的水平和垂直的旋转,PlayerHandle控制水平旋转,cameraHandle控制垂直旋转,这样我们可以很方便的控制相机。
祝你万事顺利
2019/05/29
5320
推荐阅读
相关推荐
PUN ☀️九、玩家网络实例化与昵称显示
更多 >
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验