• 麦田物语学习


    设置预设

    将对一个物体的操作保存下来,直接用于其他的物体,比较省力

    当设置好一个物体后点击箭头所指的地方,保存预设,在其他物体的面板里点击预设使用

    sprite renderer 图片渲染顺序参考点

    sorting group

    因为人物的sprite为了实现遮挡有不同的的orderlayer,但是这样的话可能因为图片太多顺序混乱然后导致身体分家,所以添加一个组件让身体合并为同一块

    修改游戏的渲染方式

    因为做的是俯视角的游戏,所以修改为按照 y 轴渲染

    这样可以实现y轴俯视角的游戏,实现自然的遮挡效果

    实现地图

    使用Tilemap,设置不同的Sorting Layer实现遮挡关系

    规则瓦片 RuleTile

    使用方法:

    瓦片地图的缝隙

    使用Map Sprite Atlas 将图片素材打包成一张图片,使用的时候就会忽略素材之间的缝隙紧密贴合在一起

    Camera 设置

    修改图片素材的碰撞关系

    实现摄像机边界功能

    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using Cinemachine;
    4. using UnityEngine;
    5. public class SwitchBounds : MonoBehaviour
    6. {
    7. private void Start()
    8. {
    9. SwitchConfinerShape();
    10. }
    11. //让CinemaChine 在切换场景后刚好能找到新场景的polygon collider 然后获取
    12. private void SwitchConfinerShape()
    13. {
    14. PolygonCollider2D confinerShape = GameObject.
    15. FindGameObjectWithTag("BoundsConfiner").GetComponent();
    16. CinemachineConfiner confiner = GetComponent();
    17. confiner.m_BoundingShape2D = confinerShape;
    18. //Call this if the bounding shape's points change at runtime
    19. //清理缓存,不清理的话可能切换场景的时候并没有实际更改边界
    20. confiner.InvalidatePathCache();
    21. }
    22. }

    背包 

    ItemDetails

    1. [System.Serializable]
    2. public class ItemDetails
    3. {
    4. public int itemID;
    5. public string name;
    6. public ItemType itemType;
    7. public Sprite itemIcon;
    8. public Sprite itemOnWorldSprite;
    9. public string itemDescription;
    10. public int itemUseRadius;
    11. public bool canPickedup;
    12. public bool canDropped;
    13. public bool canCarried;
    14. public int itemPrice;
    15. [Range(0, 1)]
    16. public float sellPercentage;
    17. }

    SO文件

    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. [CreateAssetMenu(fileName = "ItemDataList_SO",menuName = "Inventory/ItemDataList")]
    5. public class ItemDataList_SO : ScriptableObject
    6. {
    7. public List itemDetailsList;
    8. }

    UI ToolKit 与 UI Builder

     

    UI Builder

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using UnityEditor;
    5. using UnityEditor.UIElements;
    6. using UnityEngine;
    7. using UnityEngine.UIElements;
    8. public class ItemEditor : EditorWindow
    9. {
    10. private ItemDataList_SO dataBase;
    11. private List itemList = new List();
    12. private VisualTreeAsset itemRowTemplate;
    13. private ScrollView itemDetailsSection;
    14. private ItemDetails activeItem;
    15. //默认预览图片
    16. private Sprite defaultIcon;
    17. private VisualElement iconPreview;
    18. //获得VisualElement
    19. private ListView itemListView;
    20. [MenuItem("M STUDIO/ItemEditor")]
    21. public static void ShowExample()
    22. {
    23. ItemEditor wnd = GetWindow();
    24. wnd.titleContent = new GUIContent("ItemEditor");
    25. }
    26. public void CreateGUI()
    27. {
    28. // Each editor window contains a root VisualElement object
    29. VisualElement root = rootVisualElement;
    30. // VisualElements objects can contain other VisualElement following a tree hierarchy.
    31. // VisualElement label = new Label("Hello World! From C#");
    32. // root.Add(label);
    33. // Import UXML
    34. var visualTree = AssetDatabase.LoadAssetAtPath("Assets/Editor/UI Builder/ItemEditor.uxml");
    35. VisualElement labelFromUXML = visualTree.Instantiate();
    36. root.Add(labelFromUXML);
    37. //拿到模版数据
    38. itemRowTemplate = AssetDatabase.LoadAssetAtPath("Assets/Editor/UI Builder/ItemRowTemplate.uxml");
    39. //拿默认Icon图片
    40. defaultIcon = AssetDatabase.LoadAssetAtPath("Assets/M Studio/Art/Items/Icons/icon_M.png");
    41. //变量赋值
    42. itemListView = root.Q("ItemList").Q("ListView");
    43. itemDetailsSection = root.Q("ItemDetails");
    44. iconPreview = itemDetailsSection.Q("Icon");
    45. //获得按键
    46. root.Q
    47. root.Q
    48. //加载数据
    49. LoadDataBase();
    50. //生成ListView
    51. GenerateListView();
    52. }
    53. #region 按键事件
    54. private void OnDeleteClicked()
    55. {
    56. itemList.Remove(activeItem);
    57. itemListView.Rebuild();
    58. itemDetailsSection.visible = false;
    59. }
    60. private void OnAddItemClicked()
    61. {
    62. ItemDetails newItem = new ItemDetails();
    63. newItem.itemName = "NEW ITEM";
    64. newItem.itemID = 1001 + itemList.Count;
    65. itemList.Add(newItem);
    66. itemListView.Rebuild();
    67. }
    68. #endregion
    69. private void LoadDataBase()
    70. {
    71. //返回寻找的文件的GUID,返回的是一个string[]
    72. var dataArray = AssetDatabase.FindAssets("ItemDataList_SO");
    73. if (dataArray.Length > 1)
    74. {
    75. //将GUID转换为path,根据path寻找文件,因为只有一个文件,所以直接访问索引0就可以
    76. var path = AssetDatabase.GUIDToAssetPath(dataArray[0]);
    77. //返回的是 object 类型,所以需要转换一下
    78. dataBase = AssetDatabase.LoadAssetAtPath(path, typeof(ItemDataList_SO)) as ItemDataList_SO;
    79. }
    80. itemList = dataBase.itemDetailsList;
    81. //如果不标记则无法保存数据
    82. EditorUtility.SetDirty(dataBase);
    83. // Debug.Log(itemList[0].itemID);
    84. }
    85. private void GenerateListView()
    86. {
    87. Func makeItem = () => itemRowTemplate.CloneTree();
    88. Actionint> bindItem = (e, i) =>
    89. {
    90. if (i < itemList.Count)
    91. {
    92. if (itemList[i].itemIcon != null)
    93. e.Q("Icon").style.backgroundImage = itemList[i].itemIcon.texture;
    94. e.Q
    95. }
    96. };
    97. itemListView.fixedItemHeight = 50; //根据需要高度调整数值
    98. itemListView.itemsSource = itemList;
    99. itemListView.makeItem = makeItem;
    100. itemListView.bindItem = bindItem;
    101. itemListView.onSelectionChange += OnListSelectionChange;
    102. //右侧信息面板不可见
    103. itemDetailsSection.visible = false;
    104. }
    105. private void OnListSelectionChange(IEnumerable<object> selectedItem)
    106. {
    107. activeItem = (ItemDetails)selectedItem.First();
    108. GetItemDetails();
    109. itemDetailsSection.visible = true;
    110. }
    111. private void GetItemDetails()
    112. {
    113. itemDetailsSection.MarkDirtyRepaint();
    114. itemDetailsSection.Q("ItemID").value = activeItem.itemID;
    115. itemDetailsSection.Q("ItemID").RegisterValueChangedCallback(evt =>
    116. {
    117. //当面板中的数据一更新就会调用回调函数将新数值写到文件中
    118. activeItem.itemID = evt.newValue;
    119. });
    120. itemDetailsSection.Q("ItemName").value = activeItem.itemName;
    121. itemDetailsSection.Q("ItemName").RegisterValueChangedCallback(evt =>
    122. {
    123. activeItem.itemName = evt.newValue;
    124. itemListView.Rebuild();
    125. });
    126. iconPreview.style.backgroundImage = activeItem.itemIcon == null ? defaultIcon.texture : activeItem.itemIcon.texture;
    127. itemDetailsSection.Q("ItemIcon").value = activeItem.itemIcon;
    128. itemDetailsSection.Q("ItemIcon").RegisterValueChangedCallback(evt =>
    129. {
    130. Sprite newIcon = evt.newValue as Sprite;
    131. activeItem.itemIcon = newIcon;
    132. iconPreview.style.backgroundImage = newIcon == null ? defaultIcon.texture : newIcon.texture;
    133. itemListView.Rebuild();
    134. });
    135. //其他所有变量的绑定
    136. itemDetailsSection.Q("ItemSprite").value = activeItem.itemOnWorldSprite;
    137. itemDetailsSection.Q("ItemSprite").RegisterValueChangedCallback(evt =>
    138. {
    139. activeItem.itemOnWorldSprite = (Sprite)evt.newValue;
    140. });
    141. itemDetailsSection.Q("ItemType").Init(activeItem.itemType);
    142. itemDetailsSection.Q("ItemType").value = activeItem.itemType;
    143. itemDetailsSection.Q("ItemType").RegisterValueChangedCallback(evt =>
    144. {
    145. activeItem.itemType = (ItemType)evt.newValue;
    146. });
    147. itemDetailsSection.Q("Description").value = activeItem.itemDescription;
    148. itemDetailsSection.Q("Description").RegisterValueChangedCallback(evt =>
    149. {
    150. activeItem.itemDescription = evt.newValue;
    151. });
    152. itemDetailsSection.Q("ItemUseRadius").value = activeItem.itemUseRadius;
    153. itemDetailsSection.Q("ItemUseRadius").RegisterValueChangedCallback(evt =>
    154. {
    155. activeItem.itemUseRadius = evt.newValue;
    156. });
    157. itemDetailsSection.Q("CanPickedup").value = activeItem.canPickedup;
    158. itemDetailsSection.Q("CanPickedup").RegisterValueChangedCallback(evt =>
    159. {
    160. activeItem.canPickedup = evt.newValue;
    161. });
    162. itemDetailsSection.Q("CanDropped").value = activeItem.canDropped;
    163. itemDetailsSection.Q("CanDropped").RegisterValueChangedCallback(evt =>
    164. {
    165. activeItem.canDropped = evt.newValue;
    166. });
    167. itemDetailsSection.Q("CanCarried").value = activeItem.canCarried;
    168. itemDetailsSection.Q("CanCarried").RegisterValueChangedCallback(evt =>
    169. {
    170. activeItem.canCarried = evt.newValue;
    171. });
    172. itemDetailsSection.Q("Price").value = activeItem.itemPrice;
    173. itemDetailsSection.Q("Price").RegisterValueChangedCallback(evt =>
    174. {
    175. activeItem.itemPrice = evt.newValue;
    176. });
    177. itemDetailsSection.Q("SellPercentage").value = activeItem.sellPercentage;
    178. itemDetailsSection.Q("SellPercentage").RegisterValueChangedCallback(evt =>
    179. {
    180. activeItem.sellPercentage = evt.newValue;
    181. });
    182. }
    183. }

    UI版面大小根据内容量自动改变大小 

  • 相关阅读:
    护眼灯显色度越高越好吗?显色指数最舒适的护眼台灯推荐
    【vue设计与实现】内部组件和模块 1 - KeepAlive组件的实现原理
    【Linux专题】SFTP 用户配置 ChrootDirectory
    Java判断输入ip是否合法的工具类,拿上就可以使用
    Python 模拟Hermite Polynomial厄米特多项式
    Google Pixel 刷机、OpenGApps和系统分区扩容
    C++回顾录04-构造函数
    【英杰送书第三期】Spring 解决依赖版本不一致报错 | 文末送书
    Web安全—Web漏扫工具NetSparker安装与使用
    共享开源技术,共建开放生态丨平凯星辰余梦杰出席 2022 世界互联网大会开源论坛圆桌对话
  • 原文地址:https://blog.csdn.net/zaizai1007/article/details/133543482