当前位置: 首页> 娱乐> 八卦 > 百年建筑网官网_软件工程项目开发流程_网站建设技术外包_我要安装百度

百年建筑网官网_软件工程项目开发流程_网站建设技术外包_我要安装百度

时间:2025/7/16 0:35:31来源:https://blog.csdn.net/benben044/article/details/145965809 浏览次数:1次
百年建筑网官网_软件工程项目开发流程_网站建设技术外包_我要安装百度

1、目标

设置地面的属性,比如哪些地面是可以放置Items的,哪些地面可以挖洞。根据地面的这些属性,决定角色相应的动作能否顺利执行。

2、思路

我们的解决方案是:在Tilemaps中存储Boolean值信息

有些信息在设计阶段就需要进行设置:

  • Can we drop objects there?
  • Can we dig there?
  • Can we place furniture there?

另外一些信息在运行阶段进行设置:

  • Has the ground grid square(方格) been dug?
  • Has the ground grid square been watered?
  • Has a seed been planted in a ground grid square?

我们需要创建一个组件TilemapGridProperties附加到tilemap物体上。

该组件只在编辑模式下运行,并将Boolean值“yes/no - can I drop an item here”放到scriptable物体上。

每个Boolean的tilemap都会附加该组件。

3、创建新的Enum

通过枚举类GridBoolProperty定义地面的属性值,用来识别每个网格与哪个Bool属性相关。

public enum GridBoolProperty
{diggable,canDropItem,canPlaceFurniture,isPath,isNPCObstacle
}

4、创建GridCoordinate脚本

它是一个可序列化的向量,用于捕获网格坐标。

在Assets -> Scripts下创建新的目录命名为Map,在其下创建脚本命名为GridCoordinate。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;[System.Serializable]
public class GridCoordinate
{public int x;public int y;public GridCoordinate(int p1, int p2){x = p1;y = p2; }public static explicit operator Vector2(GridCoordinate gridCoordinate) {return new Vector2( (float)gridCoordinate.x, (float)gridCoordinate.y );}public static explicit operator Vector2Int(GridCoordinate gridCoordinate){   return new Vector2Int(gridCoordinate.x, gridCoordinate.y);}public static explicit operator Vector3(GridCoordinate gridCoordinate){return new Vector3((float)gridCoordinate.x, (float)gridCoordinate.y, 0f);}public static explicit operator Vector3Int(GridCoordinate gridCoordinate){return new Vector3Int(gridCoordinate.x, gridCoordinate.y, 0);}}

public static explicit operator是显式类型转换的语法。

5、创建GridProperty脚本

在Assets -> Scripts -> Map下创建新的脚本命名为GridProperty。

这个就是每个Grid方格的属性类。

属性包含:坐标,地面属性的信息。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;[System.Serializable]
public class GridProperty 
{public GridCoordinate gridCoordinate;     // 坐标public GridBoolProperty gridBoolProperty; // 地面属性public bool gridBoolValue = false;        // 是否Bool属性public GridProperty(GridCoordinate gridCoordinate, GridBoolProperty gridBoolProperty, bool gridBoolValue){this.gridCoordinate = gridCoordinate;this.gridBoolProperty = gridBoolProperty;this.gridBoolValue = gridBoolValue;}
}

6、创建SO_GridProperties脚本

该脚本存储场景下的所有方格的GridProperty数据。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;[CreateAssetMenu(fileName ="so_GridProperties", menuName ="Scriptable Objects/Grid Properties")]
public class SO_GridProperties : ScriptableObject
{public SceneName sceneName;public int gridWidth;public int gridHeight;public int originX;public int originY;[SerializeField]public List<GridProperty> gridPropertyList;
}

gridWidth/gridHeight是某一个场景的Tilemap的长宽。

originX/originY是tilemap左下角的坐标。

7、创建TilemapGridProperties脚本

在Tilemap Grid中,GridProperties对象下有对应地面属性的各种对象。

我们希望在编辑模式下,当打开GridProperties对象时,会收集Grid的信息;当关闭GridProperties对象时,会将收集的信息写入SO_GridProperties组件中。

代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.Tilemaps;[ExecuteAlways]
public class TilemapGridProperties : MonoBehaviour
{private Tilemap tilemap;[SerializeField] private SO_GridProperties gridProperties = null;[SerializeField] private GridBoolProperty gridBoolProperty = GridBoolProperty.diggable;private void OnEnable(){// Only populate in the editorif( !Application.IsPlaying(gameObject)){tilemap = GetComponent<Tilemap>();if(gridProperties != null){// 编辑模式下开启脚本,清空所有的gridPropertyList数据gridProperties.gridPropertyList.Clear();}}}private void OnDisable(){// Only populate in the editorif (!Application.IsPlaying(gameObject)) {// 编辑模式下关闭脚本,存储数据UpdateGridProperties();if(gridProperties != null){// This is required to ensure that the updated gridproperties gameobject gets saved when the game is saved - otherwise they are not saved.EditorUtility.SetDirty(gridProperties);}}}private void UpdateGridProperties(){// Compress tilemap boundstilemap.CompressBounds();// Only populate in the editorif (!Application.IsPlaying(gameObject)){if(gridProperties != null){Vector3Int startCell = tilemap.cellBounds.min;Vector3Int endCell = tilemap.cellBounds.max;for (int x = startCell.x; x < endCell.x; x++){for (int y = startCell.y; y < endCell.y; y++){TileBase tile = tilemap.GetTile(new Vector3Int(x, y, 0));if(tile != null){gridProperties.gridPropertyList.Add(new GridProperty(new GridCoordinate(x, y), gridBoolProperty, true));}}}}}}private void Update(){// Only populate in the editorif (!Application.IsPlaying(gameObject) ){Debug.Log("DISABLE PROPERTY TILEMAPS");}}
}

在编辑模式下,开启脚本时会删除历史gridProperties数据,方便重新进行绘制;关闭脚本后,会遍历Tilemap实例对应的grid,并且存储数据。

运行时,需要提醒一定要关闭脚本,因为只有在关闭状态下Tilemap实例才有gridProperties数据。

8、创建so_GridProperties实例

在Assets -> Scriptable Object Assets下创建Maps目录:

在Maps下创建Scriptable Object命名为:so_GridProperties_Scene1_Farm

点击so_GridProperties_Scene1_Farm,点击Inspector,可以看到它的属性信息。

在Hierarchy中打开Scene1_Farm,然后再点击Tile Palette,选择Coordinate Brush,在Scene中鼠标移到左下角,可以看到originX/Y的坐标信息。

然后鼠标再拖到右上角,可以看到Pos和Size信息。这正是so_GridProperties_Scene1_Farm中要填的信息。

然后添加信息如下:

以相同的方法创建so_GridProperties_Scene2_Field,其属性信息如下:

再创建so_GridProperties_Scene2_Cabin,在Scene中测量如下:

其属性信息如下:

9、添加TilemapGridProperties脚本

在Scene3_Cabin中,展开GridProperties,其下的BoolXXX全部选中,然后将TilemapGridProperties脚本添加进去。

点击BoolCanPlaceFurniture,将so_GridProperties_Scene3_Cabin资源拖入到Grid Properties属性中,Grid Bool Property属性选择和Hirerachy中物体一致的名称。如下图所示:

再看一个例子如下:

逐一操作Hierarchy中的5个GridProperties物体。

然后同样的方法在Scene1_Farm和Scene2_Field中添加TilemapGridProperties脚本,并且添加对应的so_GridProperties物体,以及选择对应的GridBoolProperty属性。

10、测试so_GridProperties物体的GridPropertyList

通过上述步骤,在编辑模式下,打开Hierarchy -> SceneXXX -> GridProperties物体(OnEnable),绘制瓦片贴图。那么关闭GridProperties物体时(OnDisable),就会自动更新so_GridProperties_Scenexxx下Grid Property List的信息。

下面测试下该功能。

点击GridProperties,然后在Inspector中进行勾选。

然后点击BoolCanDropItem,选择一个瓦片,在Scene中进行添加。

接着,点击GridProperties,然后在Inspector中进行反勾选。

最后点击so_GridProperties_Scene3_Cabin,就可以看到Grid Property List下有一个元素。

11、小结

以上内容记录了Grid的属性。

我们通过so_GridProperties实例记录每个Scene的地面属性。它记录了瓦片地图的长宽、起始坐标位置(左下角位置),以及所有的Grid的属性列表。

怎么写这个so_GridProperties实例的数据呢?我们创建了TilemapGridProperties脚本,这个脚本在编辑模型下运行,然后挂载到每个Scene下的GridProperties物体的子物体上。每个子物体会遍历各自的Tilemap地图,然后把数据写到gridProperties中。而gridProperties就是so_GridProperties实例。可以看他的定义:

 [SerializeField] private SO_GridProperties gridProperties = null;

那么Grid有哪些属性?定义在GridProperty脚本中。

关键字:百年建筑网官网_软件工程项目开发流程_网站建设技术外包_我要安装百度

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: