Simple implementation process of Unity ground screen effect

Simple implementation process of Unity ground screen effect

preface

I remember when I was in Beijing last year, I entered a company doing exhibition hall through interview. The company is very large, the boss is also very impressive, and the project is not small. After I came in, I thought I should be able to work for a long time, but I took the initiative to leave my job in less than a month. Sometimes this is the case. The greater the hope, the greater the disappointment. As for why I left the company, I was generally too tired to work, and the internal volume of the company was too strong. Those designers in the company often changed the functions of the program by themselves. They think it's easy to change the requirements. They can just write. They don't know how hard it is for programmers to change the code. There are also those who work overtime. The small leaders in charge of the project in the company will only force people to work, but there is no corresponding overtime pay and compensation after they finish their work, or even a word of thanks, as if everything is taken for granted. Maybe what I can't stand most in this company is to let me do something irrelevant to the program. This company will even let programmers install projectors, debug hardware equipment, and even manage workers' threading. Later, after I finished the Shanghai project, I planned to leave. Later, the small leader of the company asked me to do the ring shooting project, which only gave me 7 days. I haven't had a compensatory leave after the completion of the Shanghai project, which makes me work overtime every day. My heart was cold. The next day I submitted a letter of resignation to the company and left the company.
However, although I worked overtime late at night in the Shanghai project I did in this company, I did learn a lot. One of the projects I did was the ground screen interactive program. Probably, the logic is to use radar to install a rectangular display screen on the ground, and then people walk on the display screen. Where they step on the display screen, there will be a flowering pattern. At the same time, serial communication is used to send a signal to the hardware equipment to trigger the lights next to them. After waiting for someone to walk, the pattern disappears, the water animation is restored, and the touch light next to it is turned off.
The difficulty of this project is to debug the radar for touch control. I remember that the Beiyang radar was used to trigger at that time. The radar was set to click continuously, and people walked on it to simulate the effect of continuous mouse click. I debugged all night, even modified the program effect, and finally achieved a better effect. But the company didn't think of me at all. When I mentioned leaving, the leader's face was the same as a donkey's face. I asked her if I needed to hand over anything. She said I didn't do anything in the company and didn't need to hand over anything. Just in time, I'm too lazy to hand it over. It's easy. Having said so much, let's get to the point. I'll start with the general implementation steps of the project.

Implementation process

In fact, I first listened to the company's design needs. I originally designed to divide the program screen into five parts on average, and then each part becomes a touch area. People step on it through the radar to trigger the corresponding logic and produce the corresponding effect. Later, the design said no, it must be developed according to the effect done by previous programmers. Later, I looked at the code written by the previous programmers. The logic is to generate a particle effect by clicking on the screen, and then detect whether others click. If not, the particles disappear. On this basis, I further improved the code. The specific implementation steps are as follows.
1, Create a new Image component in the scene, and create a new watercolor animation on this component, as shown in the following figure:

2, Create a new particle and set the tag of the particle to grass. The particle effect and settings are as follows:

3, Create a new closegrass CS script, mount the script on the particle object, and set the particle object as a preform. The script code is shown in the following figure:

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

public class CloseGrass : MonoBehaviour
{
    //Particle effect
    public ParticleSystem[] thisParticleSystem;

    private void Start()
    {
        ToCloseThis();
    }

    /// <summary>
    ///Destroy yourself after playing the animation
    /// </summary>
    internal void ToCloseThis()
    { 
        StartCoroutine(ToDesThis());
    }

    IEnumerator ToDesThis()
    {
        yield return new WaitForSeconds(3.0f);
        for (int i = 0; i < thisParticleSystem.Length; i++)
        {
            thisParticleSystem[i].Stop();
        }
        yield return new WaitForSeconds(1.0f);
        Destroy(this.gameObject);
    }
}

4, Create a new mouseleft0 CS script to generate particle effects by clicking the mouse, and detect the number of particle effects in the scene. If the number of particles in the scene is less than 5, a new particle will be created when clicking the mouse. The script code is as follows:

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

public class MouseLeft0 : MonoBehaviour
{
    public GameObject thisImage;

    // Update is called once per frame
    void Update()
    {
        ToShowImage();
    }

    void ToShowImage()
    {
        if (Input.GetMouseButtonDown(0))
        {
            ToCheckImage();
            //Debug.Log("press the mouse!");
        }    
    }
    void ToCreateGrass()
    {
        Vector3 targetposition = Camera.main.WorldToScreenPoint(thisImage.transform.position);//Convert the world coordinates of the object to screen coordinates
        Vector3 mouseposition = Input.mousePosition;
        mouseposition.z = targetposition.z;

        float x = Camera.main.ScreenToWorldPoint(mouseposition).x;
        float y = Camera.main.ScreenToWorldPoint(mouseposition).y;
        float z = thisImage.transform.position.z;
        GameObject thisObject = GameObject.Instantiate(thisImage, new Vector3(x, y, z), Quaternion.identity);
    }
    void ToCheckImage()
    {
        GameObject[] thisGrass = GameObject.FindGameObjectsWithTag("grass");
        Debug.Log(thisGrass.Length);
        if (thisGrass.Length <= 5)
        {
            StartCoroutine(ToCreateThisGrass());
        }
        else
        {
            thisGrass[0].GetComponent<CloseGrass>().ToCloseThis();
            StartCoroutine(ToCreateThisGrass());
        }
    }

    IEnumerator ToCreateThisGrass()
    {
        yield return new WaitForSeconds(0.1f);
        ToCreateGrass();
    }
}

5, Set mouseleft0 Mount the CS script on Canvas and drag the particle preform onto the script, as shown in the following figure:
6, Click the mouse to see that the screen has produced particle effect, as shown in the following figure:

7, Next, the logic of triggering the light is completed. Serial communication is used to convert the signal into hexadecimal data. The trigger light is on or off. In the actual scene, the corresponding logic is triggered at the position where people step on. The code is as follows:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO.Ports;
using System;

public class PortManager : MonoBehaviour
{
    #region parameter
    string getPortName;
    int baudRate = 19200;
    private Parity parity = Parity.None;
    private int dataBits = 8;
    private StopBits stopBits = StopBits.One;
    SerialPort sp = null;
    private string _data;
    private string testString0, testString1, testString2, testString3, testString4, testString5,
        closeString0, closeString1, closeString2, closeString3, closeString4, closeString5;
    string reciveString;
    //Profile class
    public ConfigTest thisConfigTest;
    #endregion

    #region general method
    // Use this for initialization
    void Start()
    {
        getPortName = thisConfigTest.dic["Port number"]["portName"];
        baudRate = int.Parse(thisConfigTest.dic["Baud rate"]["baudRate"]);
        testString0 = thisConfigTest.dic["Signal 0"]["string0"];
        testString1 = thisConfigTest.dic["Signal 1"]["string1"];
        testString2 = thisConfigTest.dic["Signal 2"]["string2"];
        testString3 = thisConfigTest.dic["Signal 3"]["string3"];
        testString4 = thisConfigTest.dic["Signal 4"]["string4"];
        testString5 = thisConfigTest.dic["Signal 5"]["string5"];
        closeString0 = thisConfigTest.dic["Light off signal 0"]["closeString0"];
        closeString1 = thisConfigTest.dic["Light off signal 1"]["closeString1"];
        closeString2 = thisConfigTest.dic["Light off signal 2"]["closeString2"];
        closeString3 = thisConfigTest.dic["Light off signal 3"]["closeString3"];
        closeString4 = thisConfigTest.dic["Light off signal 4"]["closeString4"];
        closeString5 = thisConfigTest.dic["Light off signal 5"]["closeString5"];
        reciveString = thisConfigTest.dic["Receive signal"]["receiveString"];
        OpenPort(getPortName);
        StartCoroutine(DataReceiveFunction());
    }

    #endregion
    #region serial communication control

    /// <summary>
    ///Serial port signal control
    /// </summary>
    private void PortSignalControl()
    {
        if (_data == System.Text.Encoding.ASCII.GetBytes(reciveString)[0].ToString())
        {
            //Debug.Log("serial port signal received" + testString);
        }

    }
    //Open serial port
    public void OpenPort(string DefaultPortName)
    {
        sp = new SerialPort(DefaultPortName, baudRate, parity, dataBits, stopBits);
        sp.ReadTimeout = 10;
        try
        {
            if (!sp.IsOpen)
            {
                sp.Open();
            }
        }
        catch (Exception ex)
        {
            Debug.Log(ex.Message);
        }
    }
    //Close the serial port
    public void ClosePort()
    {
        try
        {
            sp.Close();
        }
        catch (Exception ex)
        {
            Debug.Log(ex.Message);
        }
    }
    IEnumerator DataReceiveFunction()
    {
        byte[] dataBytes = new byte[128];//Storage length
        int bytesToRead = 0;//Record the length of data obtained

        while (true)
        {
            if (sp != null && sp.IsOpen)
            {
                try
                {
                    //Obtain serial port data through read function
                    bytesToRead = sp.Read(dataBytes, 0, dataBytes.Length);
                    _data = dataBytes[0].ToString();
                    print(_data);
                    PortSignalControl();
                    //Serial port data has been stored in dataBytes
                }
                catch (Exception ex)
                {

                }
            }
            yield return new WaitForSeconds(Time.deltaTime);
        }
    }
    //Send a byte
    public void SendSerialPortData(string data)
    {
        if (sp.IsOpen)
        {
            sp.WriteLine(data);
        }
    }
    //Send a byte
    public void SendSerialPortData0(byte[] data)
    {
        if (sp.IsOpen)
        {
            sp.Write(data,0,data.Length);
        }
    }
    /// <summary>
    ///Send a string 0
    /// </summary>
    internal void SendString0()
    {
        //SendSerialPortData(testString0);
        SendMsg(testString0);
    }

    
    /// <summary>
    ///Send string 1
    /// </summary>
    internal void SendString1()
    {
        //SendSerialPortData(testString1);
        SendMsg(testString1);
    }
    /// <summary>
    ///Send string 2
    /// </summary>
    internal void SendString2()
    {
        //SendSerialPortData(testString2);
        SendMsg(testString2);
    }

    /// <summary>
    ///Send string 3
    /// </summary>
    internal void SendString3()
    {
        //SendSerialPortData(testString3);
        SendMsg(testString3);
    }
    /// <summary>
    ///Send string 4
    /// </summary>
    internal void SendString4()
    {
        //SendSerialPortData(testString4);
        SendMsg(testString4);
    }

    /// <summary>
    ///Send string 5
    /// </summary>
    internal void SendString5()
    {
        //SendSerialPortData(testString5);
        SendMsg(testString5);
    }

    /// <summary>
    ///Light off signal 0 occurs
    /// </summary>
    internal void SendCloseString0()
    {
        //SendSerialPortData(closeString0);
        SendMsg(closeString0);
    }

    /// <summary>
    ///Light off signal 1 occurs
    /// </summary>
    internal void SendCloseString1()
    {
        //SendSerialPortData(closeString1);
        SendMsg(closeString1);
    }
    /// <summary>
    ///Light off signal 2 occurs
    /// </summary>
    internal void SendCloseString2()
    {
        //SendSerialPortData(closeString2);
        SendMsg(closeString2);
    }

    /// <summary>
    ///Light off signal 3 occurs
    /// </summary>
    internal void SendCloseString3()
    {
        //SendSerialPortData(closeString3);
        SendMsg(closeString3);
    }

    /// <summary>
    ///Light off signal 4 occurs
    /// </summary>
    internal void SendCloseString4()
    {
        //SendSerialPortData(closeString4);
        SendMsg(closeString4);
    }

    /// <summary>
    ///Light off signal 5 occurs
    /// </summary>
    internal void SendCloseString5()
    {
        //SendSerialPortData(closeString5);
        SendMsg(closeString5);
    }

    private void OnApplicationQuit()
    {
        ClosePort();
    }
    private void OnDisable()
    {
        ClosePort();
    }

    #endregion

    #region signal to hexadecimal method


    public void SendMsg(string s)
    {
        string msg = s;
        //byte[] cmd = new byte[1024 * 1024 * 3];
        //cmd = Convert16(msg);
        //SendSerialPortData0(cmd);
        byte[] cmd = textWork16(s);
        SendSerialPortData0(cmd);
    }
    
    private byte[] textWork16(string strText)
    {
        strText = strText.Replace(" ", "");
        byte[] bText = new byte[strText.Length / 2];
        for (int i = 0; i < strText.Length / 2; i++)
        {
            bText[i] = Convert.ToByte(Convert.ToInt32(strText.Substring(i * 2, 2), 16));
        }
        return bText;
    }
    #endregion
}

8, The logic development is basically completed. The most difficult thing is to debug the radar and adjust the software effect to the best. The final effect is also good. The implementation effect is shown in the figure below:

Summary

Technology is slowly accumulated in one project after another. If there are actual projects to practice, it will become a big winner. If you have any questions or business sharing, please send me a private letter. You can also contact me on my Taobao, Xianyu or Zhuanzhuan. I will try my best to help you.

Keywords: Unity

Added by paldo on Fri, 24 Dec 2021 06:00:32 +0200