Unity RPG Dark Light problem record (1-63 terrain scene character selection walking camera follow, rotate, zoom task system panel bar backpack system status system)

001 Game Preview and Introduction

Career selection
Mouse click to move, rotate, zoom

Drug Equipment Quest NPC
Status Equipment Skill Archive

The code has changed from the original video, mainly because of the logic of the protagonist's behavior

002 Import scene resources and build the scene

3-party resources: RPG NGUI StandarAssets
enter and close automatic generation

(Problem) Model textures are missing

insert image description here
Change the Shader type (so many, one by one), and then drag the map again. Prototype Toon/Basic
insert image description here

(Problem) Terrain texture resources are missing

The paint texture is removed and repainted.
The repainted texture is blurry and the normal is not correct.

(Problem) The map is greyed out

The Terrain data file is lost, let’s do it again, it’s already the official initial document
The second possibility is lighting settings. After turning on the fog
, I found the third possibility later. The optimization of Unity makes the scene look like this when it is far away, and it recovers when it is zoomed in.
insert image description here

(Problem) Texture Paint does not go up

The texture of the surface still cannot be brushed to
Unity 3d, the reason why the texture cannot be brushed on the terrain

(Learning) Terrain's Tree tab

The Tree tab is written into the Terrain, unlike directly dragging it into the scene to move it.
The size of the brush is larger than the tree density, which can reflect random sparseness, not too neat
insert image description here

003 Add light to the scene, set the mouse pointer picture

(Understand) Default Mouse

insert image description here

004 Add water surface and sky box to the scene

(Understanding) skybox skyBox

insert image description here

005 Realize the effect of zooming in slowly

Can't find edit/lighting settings

Move to window/rendering/render setup (rendering or lighting)'
insert image description here

006 Use NGUI and white pictures to add fade-in effect to the scene

NGUI toolbar has only text

The NGUI version corresponding to unity 2018.4.32f1 is
NGUI Next-Gen UI v3.12.1 (Jun 29, 2018).
insert image description here
In one case, I created a new folder for all Assets to save them, and then re-imported them to the root directory.
insert image description here

Atlas

Here is the addition of NGUI's Button pictures. To add pictures to the atlas, you need the atlas.
Open NGUI /Open/Atlas Editor

(Problem) New failed

Unity nGUI atlas saves the file in the project resource folder
insert image description here

(learn)

Compared with the available atlases, there are two more properties of material and texture
insert image description here

(feasible) new == copy first and then modify

Comparing the available atlases, there are .mat .png .prefab files generated.
So try to copy these three, and then modify. (Feasible)
The save location is generally the same folder as the resource
insert image description here

delete

Click x, then click Delete. Delete multiple points x multiple times, Delete only needs to be clicked once
insert image description here

007 Design the initial interface, start loading button and logo

(Button) NRPG Button == Sprite + Trigger + UIButton

The trigger size is 0 by default, it needs to be propped up, as big as the button

(button show hidden)

Adding objects, there is a tag, but I think it is a waste. Direct public
.SetActive uppercase

When you press it at the beginning, the button to load the game, etc. is displayed, but you want to display it after the animation is over, and add a timer at the beginning

    {
    
    
        time -= Time.deltaTime;

        if (Input.anyKeyDown && time<=0)//因为开头有个动画,time秒后
        {
    
    
            newGameButton.SetActive(true);
            loadGameButton.SetActive(true);
            pressAnyKey.SetActive(false);
        }
    }

PlayerPrefs

PlayerPrefs comes with the system and stores key-value pairs in it

    void OnNewGame()//开始游戏
    {
    
    
        PlayerPrefs.SetInt("LoadFrom", 0);
    }
    void OnLoadGame()//加载游戏
    {
    
    
        PlayerPrefs.SetInt("LoadFrom", 1);
    }

(button sound) AudioSource has no sound

Check
the audio file (play it in the folder to see)
restart the software
AudioSource fork out, re-add
and the following:

ProjectSetting (forget what to watch, the volume is not 0?)

insert image description here

Game Mute (turn off mute)

insert image description here

Component Mute (close mute)

insert image description here

Component Volume (Try Max)

insert image description here

011 Start character creation scene, import model and UI resources

Import Modl
, add the UI of character selection to the RPG atlas (open the atlas, select the UI and click Add/Update)

NGUI button click not working

Set the camera type of UIRoot to UI
insert image description here

The NGUI toolbar cannot drag anything, and many sample scenes are damaged

Look at the example scenarios 1,2,7,9,10,12,13,14,15 and tutorial are all bad
insert image description here

(Failure) Reboot

The scene is restored, but the toolbar still cannot drag anything

(failure) change NGUI version

My unity is 2018.4.32f1.
The NGUI that cannot be used is NGUI Next-Gen UI v3.12.1.
The NGUI that can be used is NGUI Next-Gen UI v3.11.2

The NGUI that can be used is also a bit abnormal, and the style is not normal
insert image description here

(Solution) After a while it disappeared again

I found that as long as I update the RPG resources I generated, there must be a fault with NGUI, that is, there is a conflict between the two.
Then look at the picture below, there are trim and replace again, just cancel all of them and try to solve the problem temporarily

One folder and one gallery, don’t cross
folders
insert image description here

The input box of NGUI coexists with others, and PrefabTool can also be dragged and dropped

insert image description here

Atlas must have 3 files, only 2

Prefab mat missing png

You should find the .png picture from the data and drag it in. or redirect
insert image description here

After deleting NGUI, the atlas previously created by NGUI's atlas editor is damaged

Re-add into texture

(An error occurred when importing)

Shader error in 'Transparent/Refractive': Too many texture interpolators would be used for ForwardBase pass (9 out of max 8), try adding #pragma target 3.0 at line 41 did not report an error, but did not use Unity shader error: “Too many texture interpolators would be us ed for ForwardBase
insert image description here
pass

Camera for UI and scene

Separate photos, merged and displayed on the screen
insert image description here

3 o'clock lighting

material standard
insert image description here

015 Control the previous and next selection of the character

To switch roles, you need to hang on the button.
I want to read the file, that is, read the folder as a component (but I haven’t learned it, the game on the computer, the days of directly changing the data in the folder)
insert image description here


    public GameObject[] characterPrefabArray;
    public int index=0;//看的
    private GameObject[] goArray;
    // Start is called before the first frame update
    void Start()
    {
    
    

        if (characterPrefabArray.Length != 0)
        {
    
    
            //实例 隐藏
            goArray = new GameObject[characterPrefabArray.Length];
            for (int i = 0; i < characterPrefabArray.Length; i++)
            {
    
    
                goArray[i] = Instantiate(characterPrefabArray[i], transform.position, transform.rotation);
                goArray[i].SetActive(false);
                goArray[i].transform.parent = transform;
            }
            goArray[0].SetActive(true);
        }


    }

    public void PreCharacter()
    {
    
    
        goArray[index].SetActive(false);

        index = index == 0 ? (characterPrefabArray.Length - 1) : --index;
        goArray[index].SetActive(true);
    }
    public void NextCharacter()
    {
    
    
        goArray[index].SetActive(false);

        index = index == characterPrefabArray.Length - 1 ? 0 : ++index;
        goArray[index].SetActive(true);
    }

016 Handle name input and scene switching

(Problem) The input box (UIInput) of NGUI caused by the 2D box trigger cannot be clicked to enter

Description of the problem
The up and down and selection buttons can be moved, only the input box cannot be clicked

Process introduction
Section A hangs a UIInput node to receive the input box Label;
node A is referenced by the script, and uses value to get the string inside and store it in PlayerPrefs

Troubleshooting
Node A is UIRoot, no problem, but the root node of the input box is problematic (not in other scenarios).
Factors: UIRoot, Depth of the root node of the input box is 0, Label is 1, all the same
Factors: Collider, the result is a box trigger problem, choose a 2D box trigger
Factors: In this case, submit can be omitted
Factors: After the node linked to UIInput is running, the script of UI Input On GUI will be automatically added

    public void LoadScene()
    {
    
    
        PlayerPrefs.SetString("SelectedPlayerName", characterNameInput.value);
        PlayerPrefs.SetInt("SelectedPlayerIndex", index);

        print(PlayerPrefs.GetInt("SelectedPlayerIndex"));
        print(PlayerPrefs.GetString("SelectedPlayerName"));
        SceneManager.LoadScene(2);//2是数据,要分离开,但我还没学过
    }

(了解) Invalid texture used for cursor - check importer settings or texture creation. Texture must be RGBA32, readable, have alphaIsTransparency enabled and have no mip chain.

I changed this and it disappeared
Invalid texture used for cursor - check importer settings or texture creation. Texture must be RGBA3
insert image description here

(Situation) Unity saves, and there are asterisks, in the case of no error or warning

insert image description here

(Problem) The NGUI layer is black, and there is nothing after running

Modify NGUI's camera culling mask, choose default or Everything (default also works)
insert image description here

(Understanding) depth, what is in the depth will be reflected

insert image description here

018 Tag Management

With the following file, Tags.group "Group", and there will be a prompt after typing out Tags (Tags.p may have a Tags.player prompt). The
advantage is: write quickly and do not make mistakes

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

public class Tags : MonoBehaviour
{
    
    
    public const string group = "Group";
    public const string player = "Player";


}

019 Realize the click effect of character walking

    void Update()
    {
    
    
        if (Input.GetMouseButtonDown(0))
        {
    
    
            print("点击");
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);//点生成射线
            RaycastHit hit;
            bool isCollided = Physics.Raycast(ray, out hit);//是否碰到
            if (isCollided && hit.collider.tag==Tags.ground)
            {
    
    
                OnClickEffect(effectPrefab, hit.point);
            }
        }
    }

    void OnClickEffect(GameObject effectPrefab, Vector3 position)
    {
    
    
        print("Move");
        Instantiate(effectPrefab, position, Quaternion.identity);
    }

(problem) null reference

MainCamera's label
Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition) will report an empty reference

(problem) location

Not hit.collider.transfrom.position (will run to the origin of the world coordinates), but hit.point

020 Control the direction of the protagonist's movement

(Problem) When the mouse is clicked down, the player is always facing the position when the mouse is pressed and slid

During the video
, the mouse clicks down, isMoving=true
, the mouse moves up, isMoving=false,
and the process from the mouse down point to the upward movement is when the mouse is pressed all the time, the process isMoving=true, when the mouse is pressed down, the
direction is updated, and the direction is updated when the mouse is lifted up

The consequence of the above is that the Update instance is too many times, and the time is counted when the mouse is pressed

    void Update()
    {
    
    
        if (Input.GetMouseButtonDown(0))//鼠标下点
        {
    
    
            notMouseButtonUp = true;
            targetPosition = positionByRay2Tag(Input.mousePosition, Tags.ground);
            prefabByPosition(effectPrefab, targetPosition);

        }
        else if (Input.GetMouseButtonUp(0))//鼠标上抬
        {
    
    
            notMouseButtonUp = false;
        }

        
        if (notMouseButtonUp)//鼠标按着
        {
    
    
            targetPosition = targetPosition = positionByRay2Tag(Input.mousePosition, Tags.ground);          
            gameObject.transform.LookAt(targetPosition);
            //计时1秒实例 
            mouseButtonEffectTimer += Time.deltaTime;
            if (mouseButtonEffectTimer > mouseButtonEffectTime)
            {
    
    
                mouseButtonEffectTimer = 0f;
                prefabByPosition(effectPrefab, targetPosition);
            }
        }

    }
    //判断 mouseDownPosition发出的射线是否撞到标签为tag的物体,是的返回hit的位置
    Vector3 positionByRay2Tag(Vector3 mouseDownPosition, string tag)
    {
    
    
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);//点生成射线
        RaycastHit hit;
        bool isCollided = Physics.Raycast(ray, out hit);//是否碰到
        if (isCollided && hit.collider.tag == Tags.ground)
        {
    
    
            targetPosition = hit.point;
            return hit.point;
        }

        return Vector3.zero;//默认值
    }
    void prefabByPosition(GameObject prefab, Vector3 position)//在该位置实例预制体
    {
    
    
        Instantiate(prefab, position, Quaternion.identity);
    }

021 Control the movement of the main character

transform.Translate(Time.deltaTime * speed)

    void Move()
    {
    
    
        float stopDistanceNearTargetPosition = 0.2f;//可以停下的距离
        float distance = Vector3.Distance(transform.position, targetPosition);
        if (targetPosition != Vector3.zero && distance > stopDistanceNearTargetPosition)
        {
    
    
            transform.Translate(Vector3.forward * Time.deltaTime * speed);
        }
    }

Character Controller SimpleMove(speed)

    void MoveByCharacterController()
    {
    
    
        float stopDistanceNearTargetPosition = 0.2f;//可以停下的距离
        float distance = Vector3.Distance(transform.position, targetPosition);
        if (targetPosition != Vector3.zero && distance > stopDistanceNearTargetPosition)
        {
    
    
            characterController.SimpleMove(transform.forward  * speed);
        }
    }

022 Control the playback of the protagonist's movement animation

    void Update()
    {
    
    
        if (!MoveByMouse._instance.notMouseButtonUp)
        {
    
    
            animation.CrossFade("Sword-Idle");
        }
        else if (MoveByMouse._instance.notMouseButtonUp)
        {
    
    
            animation.CrossFade("Sword-Run");
        }
    }

(Problem) Players appear to run headfirst

y is the player's y

 gameObject.transform.LookAt(new Vector3(targetPosition.x, transform.position.y, targetPosition.z) );

insert image description here

(Problem) Run appears only when the mouse is pressed

Because it is based on the mouse state, not Vetor3.Distance

(Understanding) LateUpdate

Update sets state
LateUpdate sets animation

(code, understand) definition

public enum State
{
    
    
    Idle,
    Walk,
    Run
}

The public of the enumeration variable will have the style of the drop-down item
insert image description here

(code) set state

    void MoveByCharacterController()
    {
    
    
        float stopDistanceNearTargetPosition = 0.2f;//可以停下的距离
        float distance = Vector3.Distance(transform.position, targetPosition);
        if (targetPosition != Vector3.zero && distance > stopDistanceNearTargetPosition)
        {
    
    
            state = State.Run;
            characterController.SimpleMove(transform.forward * speed);
        }
        else
        {
    
    
            state = State.Idle;
        }
    }

(Code) animate based on state

   private new Animation animation;
    private State state = State.Idle;
    private MoveByMouse player;
    
    // Start is called before the first frame update
    void Start()
    {
    
    
        animation = GetComponent<Animation>();
        player = GetComponent<MoveByMouse>();
    }

    // Update is called once per frame
    void LateUpdate()
    {
    
    
        if (player.state==State.Idle)
        {
    
    
            animation.CrossFade("Sword-Idle");
        }
        else if (player.state == State.Run)
        {
    
    
            animation.CrossFade("Sword-Run");
        }
    }

023 Fix bugs and improve the movement control of the protagonist

(Issue) Walk straight after clicking, mostly on rough terrain

Especially the y value is too high, resulting in the distance has not been reached, in this case the player has been forward
insert image description here

(problem) feet dangling

025 Use the mouse to slide to control the zooming in and out of the camera field of view

the code

	public GameObject player;
	private Vector3 offset;

	//拉近
	public float scrollSpeed = 10f;//拉伸速度
	public float distance;//实际拉伸
	public float minDistance=3.2f;//最大拉伸
	public float maxDistance=30f;//最小拉伸

	// Use this for initialization
	void Start () {
    
    
		offset = transform.position - player.transform.position;
		//offset = new Vector3(0, offset.y, offset.z);//x=0,左右不偏移
	}
	
	// Update is called once per frame
	void Update () {
    
    

		transform.position =player.transform.position+ offset;
		transform.LookAt(player.transform.position);

		offset = ScrollView();
	}

	Vector3 ScrollView()//相机拉伸
	{
    
    
		distance = offset.magnitude;
		distance += scrollSpeed * Input.GetAxis("Mouse ScrollWheel");

		if (distance < minDistance)
		{
    
    
			distance = minDistance;
		}
		else if (distance > maxDistance)
		{
    
    
			distance = maxDistance;
		}
		offset = offset.normalized * distance;

		return offset;
	}

(Understanding) Clamp clamping

		distance = Mathf.Clamp(distance, minDistance, maxDistance);
		//代替下面的

		if (distance < minDistance)
		{
    
    
			distance = minDistance;
		}
		else if (distance > maxDistance)
		{
    
    
			distance = maxDistance;
		}

027 Control the left and right rotation of the field of view

(Understanding) Rotation affects the position of the camera, and the offset changes

		void RotateView()
		{
    
    			
			if (Input.GetMouseButtonDown(1))
			{
    
    
				isRotate = true;
			}
			if (Input.GetMouseButtonUp(1))
			{
    
    
				isRotate = false;
			}

			if (isRotate)
			{
    
    
				transform.RotateAround(player.transform.position, Vector3.up, rotateSpeed*Input.GetAxis("Mouse X"));
			}
			offset = transform.position - player.transform.position;//旋转影响相机的位置,offset发生变化
		}

028 Control the up and down rotation and range limitation of the field of view

the code

Press and hold the right mouse button to rotate,
the record of the upper and lower angle clamp (10, 80) value should be before RotateAround

	void RotateView()//相机旋转
		{
    
    			
			if (Input.GetMouseButtonDown(1))
			{
    
    
				isRotate = true;
			}
			if (Input.GetMouseButtonUp(1))
			{
    
    
				isRotate = false;
			}
			if (isRotate)
			{
    
    
				//记录
				Vector3 originalPosition = transform.position;
				Quaternion originalRotation = transform.rotation;
				//赋值
				transform.RotateAround(player.transform.position, transform.up, rotateSpeed * Input.GetAxis("Mouse X")); transform.RotateAround(player.transform.position, transform.right, rotateSpeed * Input.GetAxis("Mouse Y"));
				transform.RotateAround(player.transform.position, transform.right, rotateSpeed * Input.GetAxis("Mouse Y"));

				//限制范围
				if (transform.eulerAngles.x < 10 || transform.eulerAngles.x > 80)
				{
    
    
					print ("超范围了");
					transform.position = originalPosition;
					transform.rotation = originalRotation;
				}			                                           
			}

			offset = transform.position - player.transform.position;//旋转影响相机的位置,offset发生变化
		}

030 Add the NPC Grandpa to the scene

(Problem) The texture of the model is missing and it is pink

The material's type standard
insert image description here

031 Design task dialog background

(Problem, serious) The atlas information is lost, causing it to be added again

I lost it once, especially the one with buttons, it is very troublesome to add pictures.
I found that it was a copied scene. The original one is not broken, but I don’t know why the current one is broken.
insert image description here

(problem) ghosting

Perspective
insert image description here

insert image description here
Oil

(problem) wrong position

In the scene, the transfrom is 680 to 150, and the effect can be achieved.
The Tween is 700 to -1410 to achieve the desired position.
insert image description here

032 Mission system - Design mission content

(Problem) Label does not display under unity font

insert image description here
insert image description here
Add a font to the Material material, display a black font, and then drop None, white, and display normally.
It feels like a reminder to NGUI, use the font quickly.
insert image description here

(problem) multiple panels

Normally there is only one (I only have one), now after running, there is one on the left that does not move, and the one on the right is from Tween Positionbold style

(Problem) The image of Terrain appears in the NGUI layer

insert image description here
If it is too long to shine to the back,
adjust the distance of the camera.
insert image description here
Near minimum 0 far minimum 0.01
insert image description here

(Understanding) The icon in the scene is too large

Unity3D's NGUI Basics 2: Using NGUI

(Understanding) the components required for the button

The button of NGUI is equal to Sprite + UIButton + Play Sound + 2D trigger (see if the camera is 2D or 3D, the system will automatically switch)

(Solution) The button cannot be clicked

The trigger size defaults to 0, and
the attackh is not called to automatically stretch

(Understanding) GUI layer component deprecation

Unity3d 2018.3.10f1 cannot use GUI layers
insert image description here

(Problem) The coordinates of NGUI are inconsistent


The character board in the scene only shows 1/3 from x610 to x250 NGUI, and only the effect is the same from x610 to x-770

Looking at other videos, the unit of unity is meters, but here the unit is pixels.
The distance above is 360, 1380, that is, 1 meter == 2 pixels?
insert image description here

(Solution) The button of NGUI cannot be clicked

After comparing a lot, it is most convenient to delete and create a new one

(Solution) After UICamera.hoveredObject==null, click on the ground, the character does not move

After using UICamera.hoveredObject==null in unity, the game clicks the ground without response and the mouse clicks through the UI

    private void MouseDownEvent()
    {
    
    
       // if (UICamera.hoveredObject != null) return;
        if (UICamera.isOverUI) return;

        print("鼠标下按:" + UICamera.hoveredObject);

        isMouseButtonPress= true;
        targetPosition = GetTargetPosition(Input.mousePosition);
        Instantiate(effectPrefab, targetPosition, Quaternion.identity);
    }

33 Click the NPC to pop up the task board

The script hangs on the NPC, I originally wanted to hang the task board, and the task board should also be hung later


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

public class Quest : MonoBehaviour
{
    
    

    public GameObject quest;

    private void OnMouseOver()
    {
    
    
        if (Input.GetMouseButtonDown(0))
        {
    
    
            print("点击");  
            ShowQuest();
        }
    }

    void ShowQuest()
    {
    
    

        quest.GetComponent<TweenPosition>().PlayForward(); 
    }
    public void DisableQuest()
    {
    
    
        quest.GetComponent<TweenPosition>().PlayReverse();
    }
}

36 Mouse pointer management system

Image, focus, software and hardware
methods must be called, otherwise...

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

public class GameSettings : MonoBehaviour
{
    
    
    public Texture2D attackCursor;
    public Texture2D lockTargetCursor;
    public Texture2D normalCursor;
    public Texture2D npcTalkCursor;
    public Texture2D pickCursor;
    public static GameSettings _instance;

    private void Awake()
    {
    
    
        _instance = this;
    }

    public void SetNormalCursor()
    {
    
    
        Cursor.SetCursor(normalCursor, Vector2.zero, CursorMode.Auto );//图形,焦点
    }
    public void SetLockTargetCursor()
    {
    
    
        Cursor.SetCursor(lockTargetCursor, Vector2.zero, CursorMode.Auto);//图形,焦点
    }
    public void SetAttackCursor()
    {
    
    
        Cursor.SetCursor(attackCursor, Vector2.zero, CursorMode.Auto);//图形,焦点
    }
    public void SetNpcTalkCursor()
    {
    
    
        Cursor.SetCursor(npcTalkCursor, Vector2.zero, CursorMode.Auto);//图形,焦点
    }
    public void SetPickCursorr()
    {
    
    
        Cursor.SetCursor(pickCursor, Vector2.zero, CursorMode.Auto);//图形,焦点
    }

}

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

public class Npc : MonoBehaviour
{
    
    
    private void OnMouseEnter()
    {
    
    
        GameSettings._instance.SetLockTargetCursor();
    }
    private void OnMouseExit()
    {
    
    
        GameSettings._instance.SetNormalCursor();
    }
}

(Understanding) scripts have default settings

insert image description here

037 Develop function panel

01 The player clicks the button on the Bar

insert image description here

02 Trigger the function on the master node to open the panel

    public void OnStatusButtonClick()
    {
    
    
        StatusPannel._instance.ShowWindow();
    }
    public void OnBagButtonClick()
    {
    
    
        BagPannel._instance.ShowWindow();
    }
    public void OnEquipmentButtonClick()
    {
    
    
        EquipPannel._instance.ShowWindow();
    }
    public void OnSkillButtonClick()
    {
    
    
        SkillPannel._instance.ShowWindow();
    }
    public void OnSettingButtonClick()
    {
    
    
        SettingPannel._instance.ShowWindow();
    }

03 Call the parent class method ShowWindow of the corresponding panel

public class Pannel : MonoBehaviour
{
    
    
    [Tooltip("父类Window的字段,不用设置,可调用而已")] public bool isShow = false;
    [Tooltip("关闭Pannel的按钮")] public UIButton closeButton;

    public void ShowWindow()
    {
    
    
        GetComponent<TweenPosition>().PlayForward();
        isShow = true;
    }
    public void DisableWindow()
    {
    
    
        GetComponent<TweenPosition>().PlayReverse();
        isShow = false;
    }
}

39-49 backpack system

TextAsset read.txt

flow chart

insert image description here

data text

1001,小瓶血药,icon-potion1,Potion,50,0,50,60
1002,大瓶血药,icon-potion2,Potion100,0,70,100
1003,蓝药,icon-potion3,Potion,100,60,80
2001,黄金甲,armor0-icon,Equip,0,50,0,Armor,Swordman,150,200
2002,铜甲,armor1-icon,Equip,0,39,0,Armor,Swordman,100,150
2003,神迹魔法衣,armor2-icon,Equip,0,50,0,Armor,Magician,150,200
2004,破旧魔法衣,armor3-icon,Equip,0,20,0,Armor,Magician,60,100
2005,铜鞋,icon-boot0,Equip,0,0,50,Shoe,Common,60,100
2006,神级红鞋,icon-boot0-01,Equip,0,0,70,Shoe,Common,120,150
2007,帽子,icon-helm,Equip,0,50,0,Headgear,Swordman,100,120
2008,神帽,icon-helm-01,Equip,0,70,0,Headgear,Swordman,120,200
2009,神级魔法帽,icon-helm-02,Equip,0,70,0,Headgear,Magician,120,200
2010,普通魔法帽,icon-helm-03,Equip,0,50,0,Headgear,Magician,100,120
2011,黄金戒指,icon-ring,Equip,0,50,0,Accessory,Common,50,70
2012,铜绿戒指,icon-ring-01,Equip,0,30,0,Accessory,Common,30,50
2013,盾牌,icon-shield,Equip,0,50,0,LeftHand,Common,50,70
2014,神盾,icon-shield1,Equip,0,70,0,LeftHand,Common,70,100
2015,皇族项链,icon-tailman,Equip,0,30,0,Accessory,Common,30,60
2016,火柴棍,rod-icon,Equip,40,0,0,RightHand,Magician,40,80
2017,金属棍,rod-icon02,Equip,60,0,0,RightHand,Magician,60,120
2018,神级魔法棒,rod-icon03,Equip,80,0,0,RightHand,Magician,80,200
2019,御剑,sword0-icon,Equip,40,0,0,RightHand,Swordman,40,60
2020,双手剑,sword0-icon00,Equip,60,0,0,RightHand,Swordman,60,100
2021, Baidi Holy Sword, sword1-icon, Equip, 80,0,0, RightHand, Swordman, 80,150
2022, The First Sword of China, sword2-icon, Equip, 100,0,0, RightHand, Swordman, 150,200

(code) model class

Without MonoBehaviour, subsequent subclasses cannot be displayed in the editor

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

public class Item:MonoBehaviour//物品信息类
{
    
    
    public int id;//000
    public new string name;
    public string icon_name;
    public ItemType itemType;
    public int price_sell;
    public int price_buy;//5
    public DressType dressType;//部位
    public ApplyType applyType;//职业
    public int attack;
    public int defense;
    public int speed;
    public int hp;
    public int mp;


    void Start()
    {
    
    

    }
}


public enum ItemType//物品的类型
{
    
    
    Potion,
    Equip,
    Mat,
    Undefined
}

(Code) Convert TextAsset to List

The functions of the two methods are
1. Read TextAsset, write to Dictionary
2. Read Dictionary, and return an object of the above model class

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

public class TextAssetToDictionary: MonoBehaviour
{
    
    
    [Tooltip("数据文本,英文逗号分割,回车换行")]
    public TextAsset textAsset;
    [Tooltip("组件不显示,是为了让访问调用")]
    public Dictionary<int, Item> dictionary = new Dictionary<int, Item>();

    public static TextAssetToDictionary  _instance;

	void Awake()
    {
    
    
        _instance = this;
        
        dictionary = Read(textAsset);
    }

    public Dictionary<int, Item> Read(TextAsset textAsset)//读取TextAsset,存储到Dictionary
    {
    
    
        string[] lineArray = textAsset.text.Split('\n');

        foreach (string line in lineArray)
        {
    
    
            string[] propertyArray = line.Split(',');//英文逗号
            //分流
            Item item = new Item();
            item.id = int.Parse(propertyArray[0]);
            item.name = propertyArray[1];
            item.icon_name = propertyArray[2];
            //根据类型在具体赋值
            switch (propertyArray[3])
            {
    
    
                case "Potion": item.itemType = ItemType.Potion; break;
                case "Equip": item.itemType = ItemType.Equip; break;
                case "Mat": item.itemType = ItemType.Mat; break;
                default: item.itemType = ItemType.Undefined; break;
            }
            //药品
            switch (item.itemType)
            {
    
    
                case ItemType.Potion://药品
                    {
    
    
                        item.hp = int.Parse(propertyArray[4]);
                        item.mp = int.Parse(propertyArray[5]);
                        item.price_sell = int.Parse(propertyArray[6]);
                        item.price_buy = int.Parse(propertyArray[7]);
                    }
                    break;
                case ItemType.Equip://装备
                    {
    
    
                        item.attack = int.Parse(propertyArray[4]);
                        item.defense = int.Parse(propertyArray[5]);
                        item.speed = int.Parse(propertyArray[6]);

                        switch (propertyArray[7])
                        {
    
    
                            case "Headgear": item.dressType = DressType.Headgear; break;
                            case "Armor": item.dressType = DressType.Armor; break;
                            case "LeftHand": item.dressType = DressType.LeftHand; break;
                            case "RightHand": item.dressType = DressType.RightHand; break;
                            case "Shoe": item.dressType = DressType.Shoe; break;
                            case "Accessory": item.dressType = DressType.Accessory; break;
                            default:  break;
                        }
                        switch (propertyArray[8])
                        {
    
    
                            case "Swordman": item.applyType = ApplyType.Swordman; break;
                            case "Magician": item.applyType = ApplyType.Magician; break;
                            case "Common": item.applyType = ApplyType.Common; break;
                            default:break;
                        }

                        item.price_sell = int.Parse(propertyArray[9]);
                        item.price_buy = int.Parse(propertyArray[10]);
                    }
                    break;
                default:
                    break;
            }
            dictionary.Add(item.id, item);
        }
        
        return dictionary;
    }

    public Item GetItemById(int id)
    {
    
    
        dictionary.TryGetValue(id, out Item item);

        return item;
    }
}




Backpack

flow chart

ItemGroup is a group, meaning a bunch of Items, with more attributes;
I wanted to use Bag_Item before, but the same attributes in the store

The prefab of the instance is ItemGroup, inherited from Item, and the using... Start Update method of Item cannot be deleted, otherwise neither it nor its subclasses can be hung (or displayed) in the editor
insert image description here

insert image description here

(Problem) First bit generated multiple times

There is a problem with the NGUI recorded before, that is, dragging the frontmost item (often generating items)
is because clicking generates items. When dragging the first one, an empty space is formed, so the generated item is at the first place

for (int i = 0; i < gridList.Count; i++)
            {
    
    
                string itemName= itemList[itemIndex].GetComponent<UISprite>().spriteName;
                string goodName= gridList[i].childCount ==0 ? "" : gridList[i].GetChild(0).GetComponent<UISprite>().spriteName ;
                print(goodName+","+itemName);//测试
                bool isFind = (itemName==goodName);//新增的sprite名字在格子的子节点中是否能找到相同的

                if (isFind)
                {
    
    
                    print("相同");
                    IncreaseGood(i);
                    break;
                }

(Code) Get data and hang it under BagPannel

Pass each item of the dictionary to ItemGroup

  void InitItemPrefabList()//读取文本,派生Item预制体,生成对象
    {
    
    
        dictionary = GetComponent<TextAssetToDictionary>().dictionary;
        print("3423"+dictionary.Count);
        //遍历字典,填充itemPrefab,加入列表
        for (int i = 0; i < dictionary.Count; i++)
        {
    
    
            //看着文本的id来改
            Item item =new Item();
            if (i > 2)
                item = dictionary[2001 + i - 3];//药品
            //取值
            else
                item = dictionary[1001 + i];//装备

            GameObject itemPrefab = Instantiate(bag_Item);//生成
            itemPrefab.transform.parent = transform;//挂在总节点下,美观
            itemPrefab = itemPrefab.GetComponent<Bag_Item>().SetValue(item);//赋值
            itemPrefabList.Add(itemPrefab);//加入
        }
    }

(Code) ItemGroup

According to the value of the Item and the UI display, I vaguely feel that the inherited class can be used, but I have not learned that if you
inherit the Item, it will be rejected by the Monobehavior, which makes it impossible to add it in the editor.
So still treat Item as a component

(I did it), that is, the using, start, and update of the base class Item cannot be omitted, so that it cannot be dragged onto the object. I saw
ScriptableObject and introduced a single one (the video is to drag one out and fill in the value), but I have not learned its value for the time being.


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

public class ItemGroup : Item
{
    
    
    //比Item额外多的
    [Tooltip("信息提示框")] public GameObject tipGo;
    [Tooltip("信息提示框的文本")] private UILabel tipLabel;
    [Tooltip("数量的文本框")] public UILabel countLabel;
    [Tooltip("数量")] public int count = 0;
    [Tooltip("信息提示框显示时间")] public float activeTime = 0.2f;
    [Tooltip("信息提示框计时器")] public float timer = 0f;
    

    
    void Start()
    {
    
    
            
    }
    void Update()
    {
    
    
            
    }

    public void DisableTip()//信息框计时隐藏
    {
    
    
              
        tipGo.SetActive(false);

    }
    public void ShowTip()//显示提示框文本
    {
    
    
        tipGo.SetActive(true);

        string tip = "";

        switch (itemType)
        {
    
           
            case ItemType.Potion://药品
                {
    
    
                    tip = "名称:" + name;
                    tip += "\n类型:药品";
                    tip += "\n效果:Hp+" + hp;
                    tip += "\n效果:Mp+" + mp;                    
                    tip += "\n售价:" +price_sell;
                }
                break;
            case ItemType.Equip://装备
                {
    
    
                    string dressTypeStr = "";
                    switch (dressType)//部位
                    {
    
    
                        case DressType.Headgear:dressTypeStr = "头部";break;
                        case DressType.Armor:dressTypeStr = "身体";break;
                        case DressType.LeftHand:dressTypeStr = "左手";break;
                        case DressType.RightHand:dressTypeStr = "右手";break;
                        case DressType.Shoe:dressTypeStr = "脚";break;
                        case DressType.Accessory:dressTypeStr = "饰品";break;                    
                    }
                    string applyTypeStr = "";
                    switch (applyType)//职业
                    {
    
    
                        case ApplyType.Swordman: applyTypeStr = "战士"; break;
                        case ApplyType.Magician: applyTypeStr = "魔法师"; break;
                        case ApplyType.Common: applyTypeStr = "通用"; break;
                    }
                    //打印
                    tip = "名称:" + name;
                    tip += "\n类型:装备";
                    tip += "\n部位类型:"+ dressTypeStr;
                    tip += "\n职业类型:"+ applyTypeStr;
                    tip += "\n攻击:"+ attack;
                    tip += "\n防御:"+ defense;
                    tip += "\n速度:"+ speed;
                    tip += "\n售价:" + price_sell;
                }
                break;
            default:
                {
    
    
                    tip = "名称:未命名";
                    tip += "\n类型:未定义";
                }
                break;
        }
        tipLabel.text = tip;
    }
    public void SetValue(Item item)//父类的数据赋值给子类,因为数据是父类的
    {
    
    
        id=item.id;             
        name=item.name;
        icon_name=item.icon_name;
        itemType=item.itemType;
        price_sell= item.price_sell;
        price_buy= item.price_buy;
        dressType= item.dressType;
        applyType= item.applyType;
        attack= item.attack;
        defense= item.defense;
        speed = item.speed;
        hp= item.hp;
        mp= item.mp;
    }
}


(Code) Drag and Drop Components

UIDragAndDrop is rewritten and added to the item.
The grid label is Grid, and the item prefab's label is Good

using UnityEngine;

public class MyDragDrop : UIDragDropItem
{
    
    
    [Tooltip("开始拖拽的物体的位置")] private Vector3 startPos = Vector3.zero;

    protected override void OnDragDropStart()
    {
    
    
        base.OnDragDropStart();

        startPos = base.transform.position;//记录开始位置,为了回滚到原来的位置
    }
    protected override void OnDragDropRelease(GameObject surface)
    {
    
    
        base.OnDragDropRelease(surface);
        print(surface.tag);

        if (surface.tag == "Grid")
        {
    
    
            //transform.position = surface.transform.position;//物体放入格子里

            transform.parent = surface.transform;
            transform.localPosition = Vector3.zero;
        }
        else if (surface.tag == "Good")
        {
    
    
            //位置交换
            transform.position = surface.transform.position;
            surface.transform.position = startPos;
        }
        else//脱到不该脱的位置
        {
    
    
            transform.position = startPos;
        }
    }
}

(Code) Add items and hang them under BagPannel

The main node of the backpack, which is convenient for making prefabricated bodies

   void CreateNewItem(List<Transform> gridList,List<Item> itemList)//点击生成物品的测试函数,
    {
    
    
        //1 随机添加一个物品
        int createNewItemId = itemList[ Random.Range(0, itemList.Count) ].id;//新建的物品的id    

        //2 有没有相同的
        for (int i = 0; i < gridList.Count; i++)//找到图片名相同的grid的索引
        {
    
    
            if (gridList[i].transform.childCount == 0)//循环
            {
    
    
                AddNewItem(i, createNewItemId);//用拿到的id去对应的i实例
                break;
            }
            else if (gridList[i].transform.childCount > 0)
            {
    
    
                int itemGroupId = gridList[i].transform.GetChild(0).GetComponent<ItemGroup>().id;//取得格子里面的物品的id,moonobehavior排斥
                if (itemGroupId == createNewItemId)//相同,到对应的i加加
                {
    
    
                    AddExistingItem(i);
                    break;
                }
                else//循环
                {
    
    
                    if (i == gridList.Count - 1)
                        print("满了");
                }
            }
        }
    }
    void AddNewItem(int index,int id)//新增
    {
    
    
        Item item= TextAssetToList._instance.GetItemById(id);
        GameObject go = Instantiate(itemGroupPrefab);
        ItemGroup itemGroup = go.GetComponent<ItemGroup>();
        itemGroup.SetValue(item);
        go.GetComponent<UISprite>().spriteName = itemGroup.icon_name;
        go.transform.parent = gridList[index].transform;
        go.transform.localPosition = Vector3.zero;
        go.transform.localScale = Vector3.one;
      
       itemGroupList.Add(item);  
    }
    void AddExistingItem(int gridIndex)//旧增
    {
    
    
        Transform t = gridList[gridIndex].transform;//各自位置
        int count = int.Parse(t.GetChild(0).GetChild(0).GetComponent<UILabel>().text);//格子下的物品,物品下的Label对象
        t.GetChild(0).GetChild(0).GetComponent<UILabel>().text = (++count).ToString();
    }

(Understanding) the UI Trigger component

The method of displaying and hiding
the over and out of the mouse hover and dragging them into the display and hide information prompt box respectively
insert image description here

(Problem) The prompt box is not displayed in Chinese

Support Chinese fonts

(Problem) Image is too large

 go.transform.localScale = Vector3.one;

insert image description here

(问题)The root GameObject of the opened Prefab has been moved out of the Prefab …

Now just drag it out and change it, and then drag it back.
The root GameObject of the opened Prefab has been moved out of the Prefab …
insert image description here

50-52 Status system (allocation, application, reset modification of attribute points)

flow chart

insert image description here

UI

insert image description here

the code

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

public class Status : Window
{
    
    
    private int attack ;
    private int defense;
    private int speed;
    private int point;
    [Tooltip("数字部分的Label")] public UILabel attackLabel;
    [Tooltip("数字部分的Label")] public UILabel defenseLabel;
    [Tooltip("数字部分的Label")] public UILabel speedLabel;
    [Tooltip("数字部分的Label")] public UILabel pointLabel;

    // Start is called before the first frame update
    void Start()
    {
    
    
        GetValue();
        SetLabel();
    }

    //点击了相应的加按钮
    public void OnAttackClick()
    {
    
    
        bool havePoint = ConsumePoint();
        if (!havePoint) return;

        attack++;
        SetLabel();  
    }
    public void OnDefenseClick()
    {
    
    
        bool havePoint = ConsumePoint();
        if (!havePoint) return;

        defense++;
        SetLabel();
    }
    public void OnSpeedClick()
    {
    
    
        bool havePoint = ConsumePoint();
        if (!havePoint) return;

        speed++;
        SetLabel();
    }
    //够钱就扣,返回true;不然还钱,返回false
    private bool ConsumePoint()
    {
    
    
        point--;
        if (point < 0)
        {
    
    
            point++;
            return false;
        } 

        return true;
    }

    public void ResetValue ()//重置
    {
    
    
        GetValue();
        SetLabel();
    }
    public void SetValue()//应用修改
    {
    
    
        PlayerStatus._instance.attack=attack;
        PlayerStatus._instance.defense=defense;
        PlayerStatus._instance.speed=speed;
        PlayerStatus._instance.point=point;
    }

    public void GetValue()//到玩家那里获取数据
    {
    
    
        attack =  PlayerStatus._instance.attack;
        defense = PlayerStatus._instance.defense;
        speed =  PlayerStatus._instance.speed;
        point =  PlayerStatus._instance.point;
    }
    public void SetLabel()//输出到状态板的Label
    {
    
    
        attackLabel.text = attack.ToString();
        defenseLabel.text = defense.ToString();
        speedLabel.text = speed.ToString();
        pointLabel.text = point.ToString();
    }

}

There is no optional box in front of the problem component

Unity–Why is the check box in front of the script in the Inspector view gone
? After changing the name of a parent class method, TweenPosition is missing.

The background is to trigger the parent node method of the status button to call the parent method ShowWindow of the status bar.
Now try to trigger the parent node method of the status button to call the parent method ShowWindow of the status bar, which can achieve the effect,
so the problem lies in the method of the parent node.
insert image description here

53-55 store system

56-63 Equipment System

The video is worn by clicking on the equipment in the backpack

Think of it, on the UI
01 the temporary Bag is on the left, and the equipment bar is on the right,
which is convenient to drag and drop to add equipment.

need:

01. Open the equipment bar, click on the part, hide the equipment bar, pop up the backpack bar, display the player's occupation type, the type of person's equipment for this part, and then click the equipment to realize wearing or
replacement
. is stored

kind

I think that there are more count attributes than Item, and there are groups of Groups.
The frame is the UI display used to make the prefab
insert image description here

process

insert image description here

(Refactoring) Disassemble data table and object table

The background is, click on the part slot in the equipment column to enter the backpack, and the backpack will display the items that belong to the equipment of this class and this part

It comes to mind that the data is grouped into one file. This data can be all types of item tables, equipment tables, medicine tables, equipment boss commodity tables, and drug boss commodity tables.

(code) original

Correspondingly, the addition and subtraction of the quantity also needs to update the backpack, so it is redundant

    void AddNewItem(int index,int id)//新增
    {
    
    
        Item item= TextAssetToList._instance.GetItemById(id);

        GameObject go = Instantiate(itemGroupPrefab);
        ItemGroup itemGroup = go.GetComponent<ItemGroup>();
        itemGroup.SetValue(item);
        go.GetComponent<UISprite>().spriteName = itemGroup.icon_name;
        go.transform.parent = gridList[index].transform;
        go.transform.localPosition = Vector3.zero;
        go.transform.localScale = Vector3.one;
      
       itemGroupList.Add(item);  
    }

(Code) Now, take out the display part and reuse it


    void AddNewItem(int id)//新增
    {
    
     
        
        Item item= TextAssetToList._instance.GetItemById(id);
        ItemGroup itemGroup = new ItemGroup();
        itemGroup.SetValue(item);
        itemGroup.count = 1;
 
       itemGroupList.Add(itemGroup);
    }

    void DisplayItem(List<ItemGroup> itemGroupList)//拿到对应的数据表 itemGroupList,进行实例
    {
    
    
        if (itemGroupObjectList!=null)
        {
    
    
            foreach (GameObject itemGroupObject in itemGroupObjectList)
            {
    
    
                Destroy(itemGroupObject);
            }
            itemGroupObjectList.Clear();//不clear,list里面有很多Missing的对象
        }
		重新展览
        for (int i = 0; i < itemGroupList.Count; i++)
        {
    
    
            GameObject go = Instantiate(itemGroupPrefab);

            ItemGroup itemGroup = go.GetComponent<ItemGroup>();
            itemGroup.SetValue(itemGroupList[i]);
            itemGroup.countLabel.text = itemGroup.count.ToString();
            go.GetComponent<UISprite>().spriteName =itemGroup.icon_name;
            
            go.transform.parent = gridList[i].transform;
            go.transform.localPosition = Vector3.zero;
            go.transform.localScale = Vector3.one;

            itemGroupObjectList.Add(go);
        }
    }

(Question) Add the first random item in the infinite loop of the first grid

The code of the example is in the Display method, and Display is exposed in Update, not under the condition of the left mouse button.
did not destroy the previous

    void Update()
    {
    
    
        if (Input.GetKeyDown(KeyCode.Space) && _instance.isShow)//在背包打开的情况下点击
        {
    
    
            CreateNewItem(itemList);//克隆对象进背包
            DisplayItem(itemGroupList);
        }   
    }

Display again, without clearing the previous object list

    void DisplayItem(List<ItemGroup> itemGroupList)//拿到对应的数据表 itemGroupList,进行实例
    {
    
    
        itemGroupObjectList.Clear();
        for (int i = 0; i < itemGroupList.Count; i++)
        {
    
    
            GameObject go = Instantiate(itemGroupPrefab);

            ItemGroup itemGroup = go.GetComponent<ItemGroup>();
            itemGroup.SetValue(itemGroupList[i]);
            itemGroup.countLabel.text = itemGroup.count.ToString();
            go.GetComponent<UISprite>().spriteName =itemGroup.icon_name;
            
            go.transform.parent = gridList[i].transform;
            go.transform.localPosition = Vector3.zero;
            go.transform.localScale = Vector3.one;

            itemGroupObjectList.Add(go);
        }
    }

Click the equipment slot to display the equipment corresponding to the occupation and part (filter)

    //从装备栏点击进来
    public void OnDressTypeClick(DressType dressType)//筛选出 职业类型,Item类型(装备),部位类型的物品
    {
    
    
        List<ItemGroup> equipGroupList = new List<ItemGroup>();
        foreach (ItemGroup itemGroup in BagPannel._instance.itemGroupList)
        {
    
    
            if (itemGroup.dressType == dressType &&
                itemGroup.applyType == Player._instance.applyType &&
                itemGroup.itemType == ItemType.Equip)//找出职业,部位符合的装备
            {
    
    
                equipGroupList.Add(itemGroup);
            }
        }
        BagPannel._instance.DisplayItem(equipGroupList);

        this.DisableWindow();
        BagPannel._instance.ShowWindow();
    }

Left click to equip, or replace

    public void DressEquipItem(ItemGroup itemGroup)
    {
    
    
        //替换操作
        if (itemGroup.itemType != ItemType.Equip ) return;
        if (itemGroup.applyType != Player._instance.applyType && itemGroup.applyType != ApplyType.Common) return;
        

        Transform dressTrans = EquipPannel._instance.DressTypeToTransform(itemGroup.dressType);
        if (dressTrans.childCount != 0)//替换,多了回滚动作,其他一样
        {
    
    
            //卸下
            UnDressEquipItem(dressTrans.GetChild(0).GetComponent<EquipItem>());
        }

        MinusExistingItem(itemGroup.id);//减减 或者 销毁移除
        EquipPannel._instance.DressItemGroup(itemGroup);//装备
    }

The item prefab writing method passes the parameter id to BagPannel, which is called by the double-click action

    public void OnItemGroupDubleClick()
    {
    
    
        BagPannel._instance.UseItemGroup(id);
    }

insert image description here

take off

    public bool UnDressEquipItem(EquipItem equipItem)
    {
    
    
        print("bag脱下");
        if (itemGroupList.Contains(equipItem))//有同类
        {
    
    
            AddExistingItem(equipItem.id);          
        }
        if (!itemGroupList.Contains(equipItem))//无同类
        {
    
    
            if (itemGroupObjectList.Count + 1 > gridList.Count)//满了,不能卸下
            {
    
    
                return false;
            }
            AddNewItem(equipItem.id);
        }

        return true;
    }
}

The player double-clicks the EquipItem to pass the wear type to the equipment bar

    public void UndressItemGroup()
    {
    
    
        EquipPannel._instance.UndressItemGroup(dressType);
    }

insert image description here

In the equipment column, according to the type of wear, destroy the equipment on the corresponding part, roll back (add or add) the equipment to the backpack

  public void UndressItemGroup(DressType dressType)
    {
    
    
        //销毁,传id
        Transform equipTransform;
        switch (dressType)
        {
    
    
            case DressType.Headgear:
                equipTransform = headgear;
                break;
            case DressType.Armor: 
                equipTransform = anmor; 
                break;
            case DressType.LeftHand:
                equipTransform = leftHand;
                break;
            case DressType.RightHand:
                equipTransform = rightHand;
                break;
            case DressType.Shoe:
                equipTransform = shoe;
                break;
            case DressType.Accessory:
                equipTransform = accessory;
                break;
            default:
                throw new System.Exception("脱下装备出错");
            
        }
        //销毁回滚
        int id = equipTransform.GetChild(0).GetComponent<ItemGroup>().id;
        Destroy(equipTransform.GetChild(0).gameObject);
        BagPannel._instance.AddExistingItem(id);
    }

(问题) InvalidOperationException: Collection was modified; enumeration operation may not execute.

A list is modified while enumerating it

(Problem) Bug in text tooltip

Assigns to the ontology, not to an object that receives the ontology. The error text box shows the value filled in by the prefab

                ItemGroup itemGroup = go.GetComponent<ItemGroup>();
                itemGroup.SetValue(item);
				//正确
				go.GetComponent<ItemGroup>().SetValue(item);

insert image description here

(Phenomenon) Set the kerning value of the font "Miscrosoft YaHei"

Drag a ttf font to unity, and this pops up very stuck for a long time
insert image description here

Guess you like

Origin blog.csdn.net/weixin_39538253/article/details/116434641