前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Unity3D--项目:CS局域网之战(二)

Unity3D--项目:CS局域网之战(二)

作者头像
孙寅
发布2020-06-02 17:08:12
9450
发布2020-06-02 17:08:12
举报
文章被收录于专栏:宜达数字宜达数字

Image.png

1、角色控制

我们的资源里面已经包含第一人称与第三人称控制器,可以学习一番。 第一人称:

Paste_Image.png

第三人称:

Paste_Image.png

1-1、我们通过第一人称视野来进行角色控制

Paste_Image.png

最终效果:

111.gif

1-2、控制角色摄像机跟随

将摄像机移动至角色头部附近

Paste_Image.png

给摄像机添加脚本控制:

Paste_Image.png

Paste_Image.png

实际代码模块:

Paste_Image.png

1-3摄像机跟随方式二

我们除了扔进头部中,还可以扔进骨骼头部,保持相对位置,然后通过弯腰等骨骼动画来达到相机跟随

Paste_Image.png

那就添加脚本,修改相应的值 transform.localEulerAngles:自身欧拉角,说这是对象自己相对于父对象的旋转角度,该变量可用于读取和设置该角度。不可以用于递增,角度超过360度将会失效。

Paste_Image.png

修改成Y轴操纵

Paste_Image.png

注意:

1、假如产生动画后,上下视野执行不了,那么我们可以将这一套Update()更新的代码置入LateUpdate()中 原因:这是因为每一次动画执行也是在Update执行,会覆盖我们的操作,所以要在Update之后的函数中执行 2、如果发现摄像机的视野偏差太严重,可以放置在骨骼父级里面。当时一定要在有控制视野脚本的骨骼下面。

1-4、角色动画控制

将动画扔进去

Paste_Image.png

Paste_Image.png

代码语言:javascript
复制
using UnityEngine;
using System.Collections;

public class PlayerAnimation : MonoBehaviour
{

    private Animation ani;
    private CharacterController charactor;

    void Start()
    {
        ani = GetComponent<Animation>();
        charactor = GetComponent<CharacterController>();
    }

    void Update()
    {
        if (charactor.isGrounded == true)
        {
            float h = Input.GetAxis("Horizontal");
            float v = Input.GetAxis("Vertical");
            if (Mathf.Abs(h) > 0.2 || Mathf.Abs(v) > 0.2)
            {
                ani["soldierWalk"].speed = 2.0f;
                PlayAni("soldierWalk");
            }
            else
            {
                PlayAni("soldierIdle");
            }
        }
        else
        {
            PlayAni("soldierFalling");
        }
    }

    // 传入名字播放动画
    void PlayAni(string aniName)
    {
        // 控制动画播放速度
        //ani[aniName].speed = 1.0f;
        ani.CrossFade(aniName, 1.0f);
    }
1-5、关于动画的延伸

ani.Play ();播放默认动画。 ani.Play ("animation"); 将开始播放名称为animation的动画 ani.PlayQueued ("animation"); 排队播放名称为animation的动画 ani.Play ("animation", PlayMode.StopAll); 播放animation动画停止其他动画。 ani.CrossFade ("animation",1.5f);在一定时间内淡入名称为animation的动画并且淡出其他动画 ani.Stop ();停止所有动画。 ani.wrapMode = WrapMode.Loop;使用动画循环模式 WrapMode.Default:从动画剪辑中读取循环模式(默认是Once)。 WrapMode.Once:当时间播放到末尾的时候停止动画的播放。 WrapMode.Loop:当时间播放到末尾的时候重新播放从开始播放。 WrapMode.ClampForever:播放动画。当播放到结尾的时候,动画总是处于最后一帧的采样状态。

1-6、武器挂载

位置调整好,运行后查看具体效果

Paste_Image.png

1-7、制作子弹

子弹由于只需要从第一人称的视角看到,所以2D面片就可以解决这个问题

Paste_Image.png

做好保存为预制物。

1-8、子弹移动脚本

让子弹具有移动功能,首先看一张子弹运行图

Paste_Image.png

代码语言:javascript
复制
using UnityEngine;
using System.Collections;
// 子弹预制物脚本:让子弹具有移动功能

public class Bullet : MonoBehaviour {
   //子弹初始速度,开发阶段可以让其变小一些 
    private float speed = 30;
    public GameObject[] bulletoles; // 

    void Start () {
        // 3秒后摧毁子弹,不然我们的子弹会一直消耗我们的内存
        Destroy(this.gameObject, 3f);
    }
    
    void Update () {
        Vector3 currentPos = transform.position;
        transform.Translate(transform.forward * speed * Time.deltaTime);
        // 差值
        Vector3 distance = transform.position - currentPos;
        // 子弹上一帧与这一帧的距离
        float length = (transform.position - currentPos).magnitude;
        RaycastHit hit;
        // 第一个参数是开始点,第二个参数是方向,hit,最后一个是摄像-长度
        bool isCollider = Physics.Raycast(currentPos, distance, out hit, length);
        if (isCollider)
        {  // 如果检测到什么物体,应该做什么动作
           // 具体里面,在制作完相应的特效后,再写。
        } 
    }
}

Paste_Image.png

1-10、枪口特效

设置Quad将材质拖进去就可以

Paste_Image.png

因为我们的特效是跟随枪口的,伴随着子弹的射击产生的,所以扔进我们的枪中,重置坐标系,移动到合适位置。

Paste_Image.png

通过脚本来控制:枪口效果

Paste_Image.png

脚本:

代码语言:javascript
复制
using UnityEngine;
using System.Collections;
// 开枪后的枪口特效脚本:主要看到枪口的火花效果

public class PlayGunFlash : MonoBehaviour {

    // 特效数组 - 保存所有枪口特效
    public Material[] falshMaterials;
    // 获取渲染组件
    private Renderer render;
    // 当前的特效索引
    public int index;

    void Start()
    {
        render = GetComponent<Renderer>();
        // render.enabled = false;
    }

    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            render.enabled = true;
            PlayFalsh();
        }
        else
        {
            render.enabled = false;
        }
    }

    // 播放动画
    public void PlayFalsh()
    {
        index++; // 每一次调用函数,索引增加
        index %= 4; // 控制索引在[0-3]之间
        render.enabled = true; // 执行这个函数表示枪口特效要渲染出来
        render.material = falshMaterials[index];// 设置渲染器的渲染材质
    }
}

至此我们的游戏角色基本搞定,将角色保存为预制物。

2、枪的射击(不同于上面的子弹飞行脚本)

查看弹痕素材:

Paste_Image.png

如何将两张图片显示一个材质球上面呢?选中材质,更换Shader

Paste_Image.png

将拥有法线贴图的材质球设置到我们的弹痕对象中

Paste_Image.png

因为不需要碰撞检测,删除Mesh Collider,只需要修改里面材质的ManText属性的颜色通道

Paste_Image.png

如何拿到里面的材质的MainText透明通道呢?

Paste_Image.png

Paste_Image.png

代码语言:javascript
复制
public class BulletHoleRender : MonoBehaviour {
   
    private Renderer render;  // 拿到弹痕渲染器
    private float speed = 1f; // 设置渐变时间
    private float time = 0;   // 弹痕消失时间
    void Start()
    {
        render = GetComponent<Renderer>();
    }

    // Update is called once per frame
    void Update()
    {
        time += Time.deltaTime;
        if (time > 2)
        {   // 颜色渐变
            render.material.color = Color.Lerp(render.material.color, Color.clear, speed * Time.deltaTime);
        }
        if (time > 5)
        {   // 时间大于5秒,摧毁这个游戏对象
            Destroy(this.gameObject);
        }
    }
}
2-1、鼠标按键射击

首先要在我们的枪口创建一个空物体,调整位置用来挂载我们的射击脚本,实例化子弹

Paste_Image.png

代码语言:javascript
复制
using UnityEngine;
using System.Collections;
// 开火脚本,按键射击
public class ShootBullet : MonoBehaviour {
   
    private bool isFire = false;  // 是否开火
    private float timer = 0;      // 计时器
    public int shootRate = 10;    // 每秒射击多少子弹
    public PlayGunFlash playFlash;    // 播放枪口特效    
    public GameObject bullet;     // 子弹预制物

    void Update () {
        if (Input.GetMouseButtonDown(0))
        {
            isFriing = true;
        }
        if (Input.GetMouseButtonUp(0))
        {
            isFriing = false;
        }
        if (isFriing)
        {
            timer += Time.deltaTime;
            if (timer > 1f / shootRate)
            {
                Shoot();
                timer = 0;
            }
        }
    }
    void Shoot()
    {
        playFlash.PlayFalsh();
        // 实例化子弹对象到当前的物体
        GameObject.Instantiate(bulletPrefab, transform.position, transform.rotation);
    }
}
2-2、将制作好的弹痕添加到被射击的物体上面

打开上面我们做好子弹预制物挂载的脚本(让子弹飞脚本)

Paste_Image.png

修改脚本中的碰撞内容: Hit.nomal // 可以得到碰撞点的垂线向量;

Paste_Image.png

代码语言:javascript
复制
   int index = Random.Range(0, 2);
            GameObject bulletHolePrefab = bulletHoles[index];
            Vector3 po = hit.point; //拿到碰撞位置
            // 实例化弹痕
           GameObject go =  GameObject.Instantiate(bulletHolePrefab, po, Quaternion.identity) as GameObject;
           go.transform.LookAt(hit.point - hit.normal); //如果出不来,可以修改符号
           go.transform.Translate(Vector3.back * 0.01f);//移动子弹的位置

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、角色控制
    • 1-1、我们通过第一人称视野来进行角色控制
      • 1-2、控制角色摄像机跟随
        • 1-3摄像机跟随方式二
        • 注意:
          • 1-4、角色动画控制
            • 1-5、关于动画的延伸
              • 1-6、武器挂载
                • 1-7、制作子弹
                  • 1-8、子弹移动脚本
                    • 1-10、枪口特效
                    • 2、枪的射击(不同于上面的子弹飞行脚本)
                      • 2-1、鼠标按键射击
                        • 2-2、将制作好的弹痕添加到被射击的物体上面
                        领券
                        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档