当前位置: 首页 > news >正文

学习游戏制作记录(剑投掷技能)7.26

1.实现瞄准状态和接剑状态

准备好瞄准动画,投掷动画和接剑动画,并设置参数AimSword和CatchSword

投掷动画在瞄准动画后,瞄准结束后才能投掷

创建PlayerAimSwordState脚本和PlayerCatchSwordState脚本并在Player中初始化:

PlayerAimSwordState脚本:

        if(Input.GetKeyDown(KeyCode.Mouse1))//鼠标右键
{
_PlayerStateMachine.ChangeState(_Player.idleState);
}//在Update中,用于调试

PlayerGroundedState脚本:

        if(Input.GetKeyDown(KeyCode.Mouse1))
{
_PlayerStateMachine.ChangeState(_Player.AimSword);
}

为SkillManage对象创建新脚本Sword_Skil并在SkillManage脚本中初始化它:

    [Header("Skill info")]
[SerializeField] private GameObject swordPrefab;//剑的预制体
[SerializeField] private Vector2 lanchForce;//剑的发射方向
[SerializeField] private float swordGravity;//剑的重力改变

2.实现剑的投掷(剑预制体的创建与代码调用)

创建剑的对象,你可以创建一个父对象和子对象来表示一把剑,子对象负责挂载动画组件,父对象负责挂载刚体碰撞器等。

为其添加旋转和待机动画,并添加rotation参数用来控制动画

Skill脚本:

    protected Player player { get; private set; }//实例化Player,方便调用


    protected virtual void Start()
{
player = PlayerManage.instance.player;
}

为剑预制体添加Sword_Skill_Control脚本:

    private Animator anim;
private Rigidbody2D rb;
private CircleCollider2D cd;

    private Player player;

    private void Awake()
{
anim = GetComponent<Animator>();
rb = GetComponent<Rigidbody2D>(); 
cd = GetComponent<CircleCollider2D>();

}

    public void SetupSword(Vector2 _dir,float _gravityScale)//给生成的预制体一个力和重力的改变
{
rb.velocity = _dir;
rb.gravityScale = _gravityScale;
}

Sword_Skill脚本:

    public void CreateSword()
{
GameObject newSword = Instantiate(swordPrefab,player.transform.position,transform.rotation);在玩家位置创建剑对象

        Sword_Skill_Control newSkillScript =newSword.GetComponent<Sword_Skill_Control>();

        newSkillScript.SetupSword(lanchForce, swordGravity);
}

PlayerAniamtionTrigger脚本:

    private void ThrowSword()
{
SkillManage.instance.sword.CreateSword();
}//在玩家投掷动画中选择一帧添加事件来调用该函数

3.实现瞄准时方向点的生成

我们想要在玩家瞄准时随着鼠标移动展示不同的飞行轨迹并最终让剑沿着这条轨迹发射,这需要我们创建一个点的预制体,然后再游戏时生成很多个点,并套用公式让这些点排列成轨迹。

实现最终方向跟随鼠标:

Sword_Skill脚本:

private Vector2 finalDir;

    private Vector2 AnimDirection()
{
Vector2 playerPostion=player.transform.position;
Vector2 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
Vector2 direction = mousePosition - playerPostion;//由玩家指向鼠标

        return direction;
}

    protected override void  Update()
{
if(Input.GetKeyUp(KeyCode.Mouse1))
{
finalDir = new Vector2(AnimDirection().normalized.x *lanchForce.x,AnimDirection().y *lanchForce.y);//normalized是归一化处理,你可以理解把向量压缩为1,乘以我们的初始方向即最终方向
}
}

    public void CreateSword()
{
GameObject newSword = Instantiate(swordPrefab,player.transform.position,transform.rotation);

        Sword_Skill_Control newSkillScript =newSword.GetComponent<Sword_Skill_Control>();

        newSkillScript.SetupSword(finalDir, swordGravity);//调用最终方向
}

实现瞄准点的排序:

    [Header("AnimDots info")]
[SerializeField] private int numbersofDots;//生成点的数量
[SerializeField] private float spaceBetweenTwoDots;//每个点间隔的时间
[SerializeField] private GameObject dotPrefab;//点的预制体,自行创建,记得更改图层为地面
[SerializeField] private Transform dotsParent;//自行在玩家下创建一个子对象,作为生成所有点的父对象

    private GameObject[] dots;//生成点的数组

    private void GenerateDots()//生成所有点
{
dots = new GameObject[numbersofDots];
for (int i = 0; i < numbersofDots; i++)
{
dots[i]=Instantiate(dotPrefab,player.transform.position,Quaternion.identity,dotsParent);
dots[i].SetActive(false);
}
}

    protected override void Start()//调用上述函数
{
base.Start();

        GenerateDots();
}

    public void DotsActove(bool _isActive)//设置点是否可见
{
for(int i = 0; i < dots.Length; i++)//循环
{
dots[i].SetActive(_isActive);
}
}

    private Vector2 DotsPosition(float t)//返回每个点的位置
{
Vector2 position = (Vector2)player.transform.position + new Vector2(AnimDirection().normalized.x * lanchForce.x, AnimDirection().y * lanchForce.y) * t
+ .5f * (Physics2D.gravity * swordGravity) * (t * t);

//位置 = 初始位置 + 初速度 × 时间 + 0.5 × 加速度 × 时间²

        return position;
}

    protected override void  Update()
{
if(Input.GetKeyUp(KeyCode.Mouse1))
{
finalDir = new Vector2(AnimDirection().normalized.x *lanchForce.x,AnimDirection().y *lanchForce.y);
}

        if(Input.GetKey(KeyCode.Mouse1))//按住鼠标右键时时刻更新这些点的位置
{
for(int i = 0; i < dots.Length; i++)
{
dots[i].transform.position = DotsPosition(i * spaceBetweenTwoDots);
}
}
}

PlayerAimSwordState脚本:

    public override void Enter()
{
base.Enter();

        SkillManage.instance.sword.DotsActove(true);
}

    public override void Exit()
{
base.Exit();

        SkillManage.instance.sword.DotsActove(false);
}//进入瞄准时可见这些点,退出消失

演示:

http://www.dtcms.com/a/298886.html

相关文章:

  • Kotlin 数据容器 - List 扩展(转换操作、过滤操作、排序操作、分组操作、集合操作、归纳操作、窗口操作)
  • 一款基于react-native harmonyOS 封装的【文档】文件预览查看开源库(基于Harmony 原生文件预览服务进行封装)
  • 【深度之眼机器学习笔记】04-01-决策树简介、熵,04-02-条件熵及计算举例,04-03-信息增益、ID3算法
  • OpenCV图像梯度、边缘检测、轮廓绘制、凸包检测大合集
  • 今天凌晨,字节开源 Coze,如何白嫖?
  • 【Vue2】结合chrome与element-ui的网页端条码打印
  • 使用Spring Boot创建Web项目
  • QT开发---网络编程上
  • 【CTF-WEB-反序列化】利用__toString魔术方法读取flag.php
  • 传统框架与减震楼盖框架地震动力响应分析与有限元模拟
  • USB Type-c
  • 《P3313 [SDOI2014] 旅行》
  • 关于我司即将对商业间谍行为进行法律诉讼的通知
  • C++学习笔记(十:类与对象基础)
  • 洛谷刷题7.25
  • TwinCAT3编程入门1
  • 【Mybatis】分页插件及其原理
  • 蓝桥杯java算法例题
  • powershell 实现批量把文件夹下的bmp文件转换为jpg
  • 操作系统:设计与实现(Operating System Design Implementation)
  • deepseek本地部署,轻松实现编程自由
  • 小架构step系列25:错误码
  • 储粮温度预测新方案!FEBL模型用代码实现:LSTM+注意力+岭回归的完整流程
  • 【map计算】自定义map计算
  • KNN 算法进阶:从基础到优化的深度解析
  • GaussDB 数据库架构师修炼(九) 逻辑备份实操
  • 动态规划Day1学习心得
  • JavaWeb项目(纯Servlet+JSP+前端三大件)入门(从0开始)
  • JavaSE-图书信息管理系统
  • jwt 在net9.0中做身份认证