Unity3D仿星露谷物语开发46之种植/砍伐橡树

news2025/5/22 3:45:38

1、目标

种植一棵橡树,从种子变成大树。

然后可以使用斧头砍伐橡树。

2、删除totalGrowthDays字段

修改growthDays的含义,定义每个值为到达当前阶段的累加天数。此时最后一个阶段就是totalGrowthDays的含义。所以就可以删除totalGrowthDays字段。

(1)修改SO_CropDetailsList的配置信息

修改前的GrowthDays的配置信息:

修改后的GrowthDays的配置信息:

每个值换成了累加的方式。

(2)修改CropDetails.cs脚本

删除totalGrowthDays字段。

(3)修改GridPropertiesManager.cs脚本

找出目前所处的成长阶段换成如下的代码:

// 找出目前所处的成长阶段
for (int i = growthStages - 1; i >= 0; i--)
{
    if (gridPropertyDetails.growthDays >= cropDetails.growthDays[i])
    {
        currentGrowthStage = i;
        break;
    }
}

(3)修改GridCursor.cs脚本

Check if crop fully grown的逻辑修改如下:

3、修改CropStandard预制体的配置

修改CropSprite的Sprite Sort Point为Pivot。

修改CropHarvestedSprite的Sprite Sort Point为Pivot,Order in Layer为1。

调整完成后,收获的防风草会显示在Player之前,如下所示:

4、动画系统

已有的动画为:

查看TreeFallingLeft节点:

根级别的Sprite Renderer值为0,被禁用了。

子级别有Top和Trunk两个Sprite Renderer组件。

这就要求动画绑定的预设体有同样的结构。

5、创建橡树预设体

(1)创建CropTreeCanyonOak

在Hierarchy -> PersistentScene下新创建一个物体命名为CropTreeCanyonOak。

添加Box Collider 2D组件和Crop组件,相关配置信息如下:

(2)创建CropSprite

在CropTreeCanyonOak下创建子物体命名为CropSprite。

添加Sorting Group、Sprite Renderer、Animator组件,相应的配置信息如下:

双击Animator下的Controller(Tree),在Animation界面可以看到相关配置被黄色高亮显示,这表明animator识别不到相关的对象。

(3)创建Trunk

在CropSprite下创建物体命名为Trunk,添加组件信息如下:

Auto Tiling(自动贴片)的作用:要是你把 Box Collider 2D 组件添加到使用了瓦片精灵的 Sprite(精灵)上,并且开启了 Auto Tiling,这个组件就能够依据精灵的瓦片布局,自动对碰撞体的形状和大小进行调整。

  1. 贴合瓦片形状:它会按照精灵所使用的瓦片图集的边界,自动调整碰撞体的轮廓,让碰撞检测与精灵的视觉外观精准匹配。
  2. 处理多瓦片精灵:当精灵由多个瓦片组合而成时,Auto Tiling 能够自动生成一个覆盖所有瓦片的组合碰撞体,而无需你手动去调整每个瓦片的碰撞体。
  3. 提升效率:对于复杂的瓦片地图,开启 Auto Tiling 可以节省大量手动设置碰撞体的时间,避免逐个为瓦片添加碰撞体。

添加完成后,Animation下的Trunk立马置灰(正常状态)。

(4)创建Top

在CropSprite下创建子物体命名为Top,添加相关组件的配置信息如下:

添加完成后,Animation下的Top立马置灰(正常状态)。

(5)查看特效

点击CropSprite,点击Animation下的播放,可以看到特效。

(6)移动Prefab

将CropTreeCanyonOak从Hierarchy移动到Assets -> Prefabs -> Crop下。

并且删除Hierarchy下的CropTreeCanyonOak。

6、SO_CropDetailsList添加配置

因为Growth Prefab第5个Prefab已经有图片信息,所以Growth Sprite第5个不再需要图片信息。

7、运行游戏1

首先挖5块土,然后放入橡木种子。

走过未成熟的橡木时,树木会左右晃动。经过成熟的橡木后方时,会有褪色的效果。

接下来处理使用斧头砍伐成年橡树的逻辑。

8、修改GridCursor.cs脚本

修改IsCursorValidForTool函数,添加下面一行代码:

9、修改Player.cs脚本

在ProcessPlayerClickInput函数中添加一行代码:

在ProcessPlayerClickInputTool函数中,添加一个case如下:

case ItemType.Chopping_tool:
    if (gridCursor.CursorPositionIsValid)
    {
        ChopInPlayerDirection(gridPropertyDetails, itemDetails, playerDirection);
    }
    break;

添加ChopInPlayerDirection函数如下:

private void ChopInPlayerDirection(GridPropertyDetails gridPropertyDetails, ItemDetails itemDetails, Vector3Int playerDirection)
{
    // Trigger animation
    StartCoroutine(ChopInPlayerDirectionRoutine(gridPropertyDetails, itemDetails, playerDirection));    
}

添加ChopInPlayerDirectionRoutine函数如下:

private IEnumerator ChopInPlayerDirectionRoutine(GridPropertyDetails gridPropertyDetails, ItemDetails equippedItemDetails, Vector3Int playerDirection)
{
    PlayerInputIsDisabled = true;
    playerToolUseDisabled = true;

    // Set tool animation to axe in override animation
    toolCharacterAttribute.partVariantType = PartVariantType.axe;
    characterAttributeCustomisationList.Clear();
    characterAttributeCustomisationList.Add(toolCharacterAttribute);
    animationOverrides.ApplyCharacterCustomisationParameters(characterAttributeCustomisationList);

    ProcessCropWithEquippedItemInPlayerDirection(playerDirection, equippedItemDetails, gridPropertyDetails);

    yield return useToolAnimationPause;

    // After animation pause 
    yield return useToolAnimationPause;

    PlayerInputIsDisabled = false;
    playerToolUseDisabled = false;
}

修改ProcessCropWithEquippedItemInPlayerDirection如下,添加了对case ItemType.Chopping_tool的支持。

private void ProcessCropWithEquippedItemInPlayerDirection(Vector3Int playerDirection, ItemDetails equippedItemDetails, GridPropertyDetails gridPropertyDetails)
{
    switch (equippedItemDetails.itemType)
    {
        case ItemType.Chopping_tool:
            if(playerDirection == Vector3Int.right)
            {
                isUsingToolRight = true;
            }
            else if(playerDirection == Vector3Int.left)
            {
                isUsingToolLeft = true;
            }
            else if(playerDirection == Vector3Int.up)
            {
                isUsingToolUp = true;
            }
            else if(playerDirection == Vector3Int.down)
            {
                isUsingToolDown = true;
            }
            break;


        case ItemType.Collecting_tool:

                    if (playerDirection == Vector3Int.right)
                    {
                        isPickingRight = true;
                    }
                    else if (playerDirection == Vector3Int.left)
                    {
                        isPickingLeft = true;
                    }
                    else if (playerDirection == Vector3Int.up)
                    {
                        isPickingUp = true;
                    }
                    else if (playerDirection == Vector3Int.down)
                    {
                        isPickingDown = true;
                    }
                    break;

                case ItemType.none:
                    break;
                }

    // Get crop at cursor grid location
    Crop crop = GridPropertiesManager.Instance.GetCropObjectAtGridLocation(gridPropertyDetails);

    // Execute Process Tool Action For crop
    if(crop != null)
    {
        switch (equippedItemDetails.itemType)
        {
            case ItemType.Chopping_tool:
                crop.ProcessToolAction(equippedItemDetails, isUsingToolRight, isUsingToolLeft, isUsingToolDown, isUsingToolUp);
                break;

            case ItemType.Collecting_tool:
                crop.ProcessToolAction(equippedItemDetails, isPickingRight, isPickingLeft, isPickingDown, isPickingUp);
                break;
        }
    }
}

10、运行游戏2

存在一个问题:就是砍树的时候,用的不是斧头,而是锄头。这是因为使用了默认的Tool即Hoe。

之前,当玩家携带一个道具时,我们为动画创建了一些脚本对象资产,以便可以在携带道具和不携带之间切换。

现在,我们需要对use tool动画做类似的事情,以便在axe和hoe两个工具之间切换。

11、新建Animation Type

在Assets -> Scriptable Object Assets -> Animation -> Animation Types下新建tool目录,在其下再创建目录NoneAxe。

该目录右击,Create -> Scriptable Objects -> Animation -> Animation Type,重命名为ToolNoneAxeUseToolDown。

配置ToolNoneAxeUseToolDown的相关信息:

以同样的方式,分别创建ToolNoneAxeUseToolLeft、ToolNoneAxeUseToolRight、ToolNoneAxeUseToolUp。

比如ToolNoneAxeUseToolRight的参数如下:

在tool目录下再创建目录NoneHoe,相应地创建4个AnimationType,比如ToolNoneHoeUseToolDown如下:

在tool目录下再创建目录NoneScythe,相应地创建4个AnimationType,比如ToolNoneScytheSwingToolDown如下:

在tool目录下再创建目录NoneWateringCan,相应地创建4个AnimationType,比如ToolNoneWateringCanLiftToolUp如下:

新建完毕后,将上面16个添加到Player的CharacterCustomiser下:

添加完毕后,相应的数量从24变为40。

12、运行游戏3

再次砍树,发现正确使用了斧头这个工具

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2381962.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

gRPC开发指南:Visual Studio 2022 + Vcpkg + Windows全流程配置

前言 gRPC作为Google开源的高性能RPC框架,在微服务架构中扮演着重要角色。本文将详细介绍在Windows平台下,使用Visual Studio 2022和Vcpkg进行gRPC开发的完整流程,包括环境配置、项目搭建、常见问题解决等实用内容。 环境准备 1. 安装必要组…

高密度服务器机柜散热方案:高风压风机在复杂风道中的关键作用与选型要点

随着云计算、人工智能等技术的飞速发展,数据中心内服务器机柜的集成度不断攀升,高密度部署成为常态。然而,高密度意味着单位空间内服务器数量剧增,发热量呈指数级上升,传统散热方案已难以满足需求。在复杂的机柜风道环…

框架之下再看HTTP请求对接后端method

在当今的软件开发中,各类框架如雨后春笋般不断涌现,极大地提升了开发效率。以 Java 开发为例,Spring 框架历经多次迭代演进,而 Spring Boot 更是将开发便捷性提升到了新高度。如今,开发者只需简单引入 Maven 包&#x…

【笔记】与PyCharm官方沟通解决开发环境问题

#工作记录 2025年5月20日 星期二 背景 在此前的笔记中,我们提到了向PyCharm官方反馈了几个关于Conda环境自动激活、远程解释器在社区版中的同步问题以及Shell脚本执行时遇到的问题。这些问题对日常开发流程产生了一定影响,因此决定联系官方支持寻求解…

node.js文件系统(fs) - 创建文件、打开文件、写入数据、追加数据、读取数据、创建目录、删除目录

注意:以下所有示例均是异步语法! 注意:以下所有示例均是异步语法! 创建文件 node.js 允许我们在计算机本地创建文件,例如创建一个 word 文件: // 引入核心模块(fs) var fs require(fs)// API fs.writeF…

利用ffmpeg截图和生成gif

从视频中截取指定数量的图片 ffmpeg -i input.mp4 -ss 00:00:10 -vframes 1 output.jpgffmpeg -i input.mp4 -ss 00:00:10 -vframes 180 output.jpg -vframes 180代表截取180帧, 实测后发现如果视频是60fps,那么会从第10秒截取到第13秒-i input.mp4:指定输入视频文…

初始化一个Springboot项目

初始化一个Springboot项目 文章目录 初始化一个Springboot项目1、新建项目2、配置yml3、自定义异常4、通用相应类5、全局跨域配置6、总结 1、新建项目 首先,我们需要创建一个新的 Spring Boot 项目。这里我们使用 IntelliJ IDEA 作为开发工具,它提供了方…

YOLOv8在单目向下多车辆目标检测中的应用

大家读完觉得我有帮助记得关注!!! 摘要 自动驾驶技术正逐步改变传统的汽车驾驶方式,标志着现代交通运输的一个重要里程碑。目标检测是自主系统的基石,在提高驾驶安全性、实现自主功能、提高交通效率和促进有效的应急…

Baklib构建AI就绪型知识中台实践

Baklib驱动企业知识资产重构 在数字化转型浪潮中,企业知识中台的构建已成为激活数据价值的关键路径。Baklib通过结构化存储与智能分类引擎,将分散于邮件、文档、IM工具中的碎片化信息转化为可检索、可复用的数字资产。其核心能力体现在三个维度&#xf…

JS逆向-某易云音乐下载器

文章目录 介绍下载链接Robots文件搜索功能JS逆向**函数a:生成随机字符串****函数b:AES-CBC加密****函数c:RSA公钥加密** 歌曲下载总结 介绍 在某易云音乐中,很多歌曲听是免费的,但下载需要VIP,此程序旨在“…

服务器的基础知识

什么是服务器 配置牛、运行稳、价格感人的高级计算机,家用电脑不能比拟的。 服务器的组成:电源、raid卡、网卡、内存、cpu、主板、风扇、硬盘。 服务器的分类 按计算能力分类 超级计算机 小型机AIX x86服务器(服务器cpu架构) …

Python连接redis

第一步安装redis Releases microsoftarchive/redis 安装时勾上所有能勾上的选项下一步即可 在CMD中pip install redis 安装redis pip install redis -i https://pypi.tuna.tsinghua.edu.cn/simple 配置redis 在redis安装目录下找到 修改 line 57 bind 0.0.0.0 line…

使用exceljs将excel文件转化为html预览最佳实践(完整源码)

前言 在企业应用中,我们时常会遇到需要上传并展示 Excel 文件的需求,以实现文件内容的在线预览。经过一番探索与尝试,笔者最终借助 exceljs 这一库成功实现了该功能。本文将以 Vue 3 为例,演示如何实现该功能,代码示例…

前端面经12 函数柯里化

<script>function sum(num){return function(num2){return numnum2}}console.log(sum(1)(2))</script>面试考察 只要参数够了 达到某个数量就输出 <script>let nums[]function sum(...args){nums.push(...args)if(nums.length>5){const out (nums.slice…

告别蜘蛛池!PHP 打造你的网站专属蜘蛛导航仪

在网站优化的赛道上&#xff0c;吸引搜索引擎蜘蛛来访一直是站长和开发者关注的重点。以往借助蜘蛛池、软件等工具引蜘蛛&#xff0c;不仅存在成本高、易违规的风险&#xff0c;效果也参差不齐。现在&#xff0c;有一种更高效、更安全的方式 —— 利用 PHP 代码&#xff0c;无需…

ubuntu kubeasz 部署高可用k8s 集群

ubuntu kubeasz 部署高可用k8s 集群 测试环境主机列表软件清单kubeasz 部署高可用 kubernetes配置源配置host文件安装 ansible 并进行 ssh 免密登录:下载 kubeasz 项⽬及组件部署集群部署各组件开始安装修改 config 配置文件增加 master 节点增加 kube_node 节点登录dashboard…

芯驰科技与安波福联合举办技术研讨会,深化智能汽车领域合作交流

5月15日&#xff0c;芯驰科技与全球移动出行技术解决方案供应商安波福&#xff08;Aptiv&#xff09;在上海联合举办以“芯智融合&#xff0c;共赢未来”为主题的技术研讨会。会上&#xff0c;双方聚焦智能座舱与智能车控的发展趋势&#xff0c;展开深入交流与探讨&#xff0c;…

【论文#目标检测】End-to-End Object Detection with Transformers

目录 摘要1.引言2.相关工作2.1 集合预测2.2 Transformer和并行解码2.3 目标检测 3.DETR模型3.1 目标检测集合预测损失3.2 DETR架构 4.实验4.1 与Faster R-CNN的比较4.2 消融研究4.3 分析4.4 DETR用于全景分割 5.结论6.致谢 Author: Nicolas Carion, Francisco Massa, Gabriel S…

Elasticsearch 深入分析三种分页查询【Elasticsearch 深度分页】

前言&#xff1a; 在前面的 Elasticsearch 系列文章中&#xff0c;分享了 Elasticsearch 的各种查询&#xff0c;分页查询也分享过&#xff0c;本篇将再次对 Elasticsearch 分页查询进行专题分析&#xff0c;“深度分页” 这个名词对于我们来说是一个非常常见的业务场景&#…

DAY29 超大力王爱学Python

知识点回顾 类的装饰器装饰器思想的进一步理解&#xff1a;外部修改、动态类方法的定义&#xff1a;内部定义和外部定义 作业&#xff1a;复习类和函数的知识点&#xff0c;写下自己过去29天的学习心得&#xff0c;如对函数和类的理解&#xff0c;对python这门工具的理解等&…