p=67-68 SwordThrow State (扔剑状态),准备阶段 ;类恶魔城Demo学习(记录)

实现功能:1、设置剑状态(生成) 2、让剑扔出抛物线(p68) 3、显示抛物线瞄准线(p68)

p=67 SwordThrow State (扔剑状态),准备阶段 ;类恶魔城Demo学习(记录)

首先新建玩家瞄准状态和扔剑的状态和动画(游戏的远程 瞄准状态->射击中状态)

实现思路是我们创一个预制体(剑),这个预制体受到移动方向(玩家瞄准的坐标)和重力影响。所以我们这去剑技能里新建三个变量。

流程:通过玩家扔剑动画Even触发 playerAnimation脚本的ThrowSword方法 ->然后调用SkillSword的CreateSword(创建物体)->剑技能脚本(互动)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Sword_Skill : Skill
{
    [Header("Skill Info")]
    [SerializeField] private GameObject sword;
    [SerializeField] private Vector2 launch; //玩家瞄准的坐标,既扔出去的方向
    [SerializeField] private float swordGravity;   //扔出去会受到重力印象
    
}

p68:
设置剑扔出去的方向(想让剑随着鼠标准星的地方扔)

思路:获取鼠标和玩家之间的向量,然后这个向量传入Controller脚本设置(参数为launchForce和gravity)
获取向量:先获取玩家和瞄准的坐标,两者相减得向量(xy的差距),最后用Vector2的normalized方法得向量的摸(向量方向)* 力度就为剑要生成后移动的最终方向了。

    [Header("Skill Info")]
    [SerializeField] private GameObject swordPrefab;  //unity放入对象
    [SerializeField] private Vector2 launchForce; //既扔出去的力度,乘于向量的摸(方向)
    [SerializeField] private float swordGravity;   //扔出去会受到重力印象
    private Vector2 finaDir;   //最终方向
    protected override void Update()
    {
        if (Input.GetKeyUp(KeyCode.Mouse1)) 
        {
            //飞的方向 = x的向量的摸* 力度(因为有重量影响)
            finaDir = new Vector2(Aim().normalized.x * launchForce.x, Aim().normalized.y * launchForce.y);
        }
    }
    
    public Vector2 Aim()
    {
        Vector2 playerPosition =  player.transform.position;
        //获取摄像头位置(参数鼠标输入的位置)
        Vector2 animPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        //获取向量,xy的差
        Vector2 distance = playerPosition - animPosition;
        return distance;
    }

开始制作瞄准辅助线:
思路:其实就是生成多个预制点(一整条下来就是瞄准线了)。辅助线(抛物线)生成的位置也是类似上面算出向量。不同的是因为有重力系统(抛物线),要用向量方向(带力量)* 物理变量(既位移公式 :X=V0t+1/2at2的2/1at2)。
在这里插入图片描述

先声明变量:

//辅助线   ``````
[Header("Aim dost Info")]
[SerializeField] private int numberOfDots;  //多少个点,作用for的变量来创造多个
[SerializeField] private float spaceBetweenDots;    //点和点之间的空间(距离)
[SerializeField] private GameObject dotPrefab;      //点的样子(对象)
[SerializeField] private Transform dotsParent;      //父类

private GameObject[] dots;   //数组存储这个线

第一步:创造出这些点:(Instantiate)

  public void GenerateDots()
{
    //上面声明了dots,这里new数组
    dots = new GameObject[numberOfDots];
    for(int i =0; i < numberOfDots; i++)
    {
        //第四个为Transform Parent
        //克隆物体original,拥有父物体,
        //其Position和Rotation由人为设置,
        //而且这里设置的坐标是世界坐标,不是localposition
        dots[i] = Instantiate(dotPrefab, player.transform.position,
        Quaternion.identity, dotsParent);
        dots[i].SetActive(false) ;
    }
}

第二步:新创一个方法设置点的激活情况(T/F)
在PlyaerAimState 进入时设置True;
在本SwordSkill的CreateSwird最后设置False //因为扔剑时就不需要辅助线了

    public void DotsAtive(bool _IsActive)
    {
        //改状态,是否激活
        for (int i = 0; i < dots.Length; i++)
        {
            dots[i].SetActive(_IsActive);
        }
    }

第三步:调整这些点的位置,连成一个抛物线(用起点点 + 算出向量方向 * 时间 (各个点的间隔)* 重力)

//调点的位置。t为时间(我们这用i* 各点间隔 表示)
private Vector2 DotsPosition(float t)
{
    //起点坐标+加速位移的坐标
    Vector2 position = (Vector2)player.transform.position + new Vector2(
        AimDirection().normalized.x * launchForce.x,
        AimDirection().normalized.y * launchForce.y) * t +  0.5f * (Physics2D.gravity * swordGravity) *(t * t);
    //位移公式 :X=V0t+1/2at2的2/1at2   往下的位移(重力抛物)
    return position;
}

最后一步:Start生成辅助点,update当玩家瞄准时调整点的位置:

    protected override void Start()
    {
        base.Start();
        GenerateDots();
    }

    protected override void Update()
    {
        if (Input.GetKey(KeyCode.Mouse1)) 
        {
            for (int i = 0; i < numberOfDots; i++) 
            {
                dots[i].transform.position = DotsPosition(i * spaceBetweenDots);
            }
        }
    }

本页面完整代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SwordSkill : Skill
{
    [Header("Skill Info")]
    [SerializeField] private GameObject swordPrefab;  //unity放入对象
    [SerializeField] private Vector2 launchForce; //既扔出去的力度,乘于向量的摸(方向)
    [SerializeField] private float swordGravity;   //扔出去会受到重力印象
    //             ``
    //            `  ``
    //辅助线   ``````
    [Header("Aim dost Info")]
    [SerializeField] private int numberOfDots;  //多少个点,作用for的变量来创造多个
    [SerializeField] private float spaceBetweenDots;    //点和点之间的空间(距离)
    [SerializeField] private GameObject dotPrefab;      //点的样子(对象)
    [SerializeField] private Transform dotsParent;      //父类

    private GameObject[] dots;   //数组存储这个线

    private Vector2 finaDir;   //最终方向

    protected override void Start()
    {
        base.Start();
        GenerateDots();
    }

    protected override void Update()
    {
        if (Input.GetKeyUp(KeyCode.Mouse1)) 
        {
            //飞的方向 = x的向量的摸* 力度(因为有重量影响)
            finaDir = new Vector2(AimDirection().normalized.x * launchForce.x, AimDirection().normalized.y * launchForce.y);
        }
        if (Input.GetKey(KeyCode.Mouse1)) 
        {
            for (int i = 0; i < numberOfDots; i++) 
            {
                dots[i].transform.position = DotsPosition(i * spaceBetweenDots);
            }
        }
    }
    public void CreatSword()
    {
        GameObject newSword = Instantiate(swordPrefab,player.transform.position,transform.rotation);

        Sword_Skill_Controller newSwordScript = newSword.GetComponent<Sword_Skill_Controller>();
        //newSwordScript.SetupSword(launch, swordGravity);  旧的
        //也可以newSword.GetComponent<Sword_Skill_Controller>().SetupSword(a参数,b参数);
        //这样调用的SetupSword方法可以把newSword传入,里面的tranfrom就是newSword的tranfrom

        //调用剑的脚本ConTroller,在里面设置到组件上面
        newSwordScript.SetupSword(finaDir, swordGravity);

        DotsAtive(false);  //开始扔剑时就把辅助线关了
    }
    public Vector2 AimDirection()
    {
        Vector2 playerPosition =  player.transform.position;
        //获取摄像头位置(参数鼠标输入的位置)
        Vector2 animPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        //获取向量,xy的差
        Vector2 distance = animPosition - playerPosition ;
        return distance;
    }
    public void DotsAtive(bool _IsActive)
    {
        //改状态,是否激活
        for (int i = 0; i < dots.Length; i++)
        {
            dots[i].SetActive(_IsActive);
        }
    }
    //生成点
    public void GenerateDots()
    {
        //上面声明了dots,这里new数组
        dots = new GameObject[numberOfDots];
        for(int i =0; i < numberOfDots; i++)
        {
            //第四个为Transform Parent
            //克隆物体original,拥有父物体,
            //其Position和Rotation由人为设置,
            //而且这里设置的坐标是世界坐标,不是localposition
            dots[i] = Instantiate(dotPrefab, player.transform.position,
            Quaternion.identity, dotsParent);
            dots[i].SetActive(false) ;
        }
    }
    //调点的位置。t为时间(我们这用i* 各点间隔 表示)
    private Vector2 DotsPosition(float t)
    {
        //起点坐标+加速位移的坐标
        Vector2 position = (Vector2)player.transform.position + new Vector2(
            AimDirection().normalized.x * launchForce.x,
            AimDirection().normalized.y * launchForce.y) * t +  0.5f * (Physics2D.gravity * swordGravity) *(t * t);
        //位移公式 :X=V0t+1/2at2的2/1at2   往下的位移(重力抛物)
        return position;
    }
}

### 恶魔城游戏的源代码获取 恶魔城游戏通常指的是具有横版卷轴、探索性强以及高难度战斗的游戏风格。如果希望找到似的开源项目或者学习如何开发这样的游戏,可以考虑以下几个方面: #### 开源项目的查找方式 可以通过一些知名的代码托管平台来寻找恶魔城游戏的开源实现。GitHub 是目前最常用的代码托管服务之一,在其中搜索关键词如 `Metroidvania` 或者 `Castlevania-like game` 可能会发现许多有价值的资源[^1]。 对于具体下载地址,由于网络环境变化频繁,建议直接访问 GitHub 并输入上述关键字进行检索。例如,“Metroidvania Game Engine” 就是一个基于 Godot 游戏引擎构建的例子[^2]。 另外还有 itch.io 这样的独立开发者社区也经常分享完整的项目文件供爱好者研究学习[^3]。 #### 使用特定框架简化开发过程 除了现成的完整作品外,还可以利用某些专为制作此游戏设计的技术栈来自行搭建原型。比如 Unity 和 Unreal Engine 都提供了丰富的插件支持;而像 Godot 则因为其轻量级特性和内置脚本语言 GDScript 更适合初学者快速上手创建简单的 Metroidvania 型产品[^4]。 下面展示一段基本的角色移动逻辑作为参考: ```csharp // C# Example for Unity using UnityEngine; public class PlayerMovement : MonoBehaviour { public float speed = 5f; void Update() { float moveHorizontal = Input.GetAxis("Horizontal"); Vector3 movement = new Vector3(moveHorizontal, 0.0f, 0.0f); transform.position += movement * Time.deltaTime * speed; } } ``` 请注意以上仅为演示目的编写的小片段,并未包含碰撞检测等功能模块[^5]。 #### 法律与版权注意事项 无论从何处获得代码素材,请务必确认该软件许可协议允许二次分发或商业用途等活动之前就擅自行动可能导致侵权风险【^6】。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值