movement control with mouse clicks

Greetings. I am making a mega masterpiece, but I am not strong in programming, as well as in English.

How to make controls from old games, Dune, Red Alert. Ortho view. Selection of one object, selection with a frame, movement, is carried out with one mouse button. Are there ready-made solutions?

I need help.

Better than that there are ready- made tutorials. Nobody here is going to retype them into a forum box for you,

7598389--942757--Screen Shot 2021-10-24 at 7.38.13 AM.jpg

Tutorials and example code are great, but keep this in mind to maximize your success and minimize your frustration:

How to do tutorials properly:

Tutorials are a GREAT idea. Tutorials should be used this way:

Step 1. Follow the tutorial and do every single step of the tutorial 100% precisely the way it is shown. Even the slightest deviation (even a single character!) generally ends in disaster. That’s how software engineering works. Every single letter must be spelled, capitalized, punctuated and spaced (or not spaced) properly. Fortunately this is the easiest part to get right. Be a robot. Don’t make any mistakes. BE PERFECT IN EVERYTHING YOU DO HERE.

If you get any errors, learn how to read the error code and fix it. Google is your friend here. Do NOT continue until you fix the error. The error will probably be somewhere near the parenthesis numbers (line and character position) in the file. It is almost CERTAINLY your typo causing the error, so look again and fix it.

Step 2. Go back and work through every part of the tutorial again, and this time explain it to your doggie. See how I am doing that in my avatar picture? If you have no dog, explain it to your house plant. If you are unable to explain any part of it, STOP. DO NOT PROCEED. Now go learn how that part works. Read the documentation on the functions involved. Go back to the tutorial and try to figure out WHY they did that. This is the part that takes a LOT of time when you are new. It might take days or weeks to work through a single 5-minute tutorial. Stick with it. You will learn.

Step 2 is the part everybody seems to miss. Without Step 2 you are simply a code-typing monkey and outside of the specific tutorial you did, you will be completely lost. If you want to learn, you MUST do Step 2.

Of course, all this presupposes no errors in the tutorial. For certain tutorial makers (like Unity, Brackeys, Imphenzia, Sebastian Lague) this is usually the case. For some other less-well-known content creators, this is less true. Read the comments on the video: did anyone have issues like you did? If there’s an error, you will NEVER be the first guy to find it.

Beyond that, Step 3, 4, 5 and 6 become easy because you already understand!

Finally, when you have errors…

Remember: NOBODY here memorizes error codes. That’s not a thing. The error code is absolutely the least useful part of the error. It serves no purpose at all. Forget the error code. Put it out of your mind.

The complete error message contains everything you need to know to fix the error yourself.

Always start with the FIRST error in the console window, as sometimes that error causes or compounds some or all of the subsequent errors.

The important parts of the error message are:

  • the description of the error itself (google this; you are NEVER the first one!)
  • the file it occurred in (critical!)
  • the line number and character position (the two numbers in parentheses)
  • also possibly useful is the stack trace (all the lines of text in the lower console window)

All of that information is in the actual error message and you must pay attention to it. Learn how to identify it instantly so you don’t have to stop your progress and fiddle around with the forum.

1 Like

Many thanks. You have written a successful query for a search engine.

While I am studying the tutorials, I will hope that someone will post a ready-made script with detailed comments.

The script is a teeny tiny part of the problem, just the tip of the iceberg. Even if you had a “ready made script” given to you by a Unity forum unicorn, you would still need to integrate it in your scene, create the prefabs, connect all the animations, pathfinding, obstacle avoidance, crowd control, just about everything else.

The script is nothing. It’s just some code.

Perhaps what you need is a complete RTS engine from the asset store. There’s lots of those!

Here’s one:

https://assetstore.unity.com/packages/templates/packs/rts-engine-79732

With this attitude you won’t get very far in game development. Or in any other value creating endeavour.

Those probably have to be adapted in one way or the other. Since most code assets don’t fit your needs perfectly you either live with these “shortcomings” or make it work the way you want. So Assets are a great start and save you some time, but they are rarely a “make game button” and still need some additional work.

But I fear OP has a misconception here that game development is just copying code snippets together to receive a “perfect” game. But the important part is “development” which means adaption, invention, beeing creative, getting some “inspiration” and making something out of it. Just copying is not development. So if you really want to make games stop waiting until someone gives you the code, but starting to write what you need yourself. Or stop right here as most people have better things to do than writing code for strangers on the internet for free.

If you have difficulties with coding there are many roles to fill in game development (designers, artists, writers). But then you still need to find someone to write the code for you and “rely” on that he/she does it the way you want. So my suggestion is to learn coding for example with the free C# Yellow book by Rob Miles.

Wait… it’s not?!

https://discussions.unity.com/t/824893/2

“… I know that grabbing random scripts off the internet and hoping they will work is NOT actually software engineering.” - Kurt Dekker

1 Like

You are right about that.

Think shallowly. First you need to open America again. Then he will reinvent the wheel and learn to program in assembly language. Does it work like that? These algorithms are 20 years old. The hardest code has already been written, this is the game engine. It will also be hard to write artificial intelligence. Anything else can be done by a beginner like me. I am not doing absolutely anything new! I restore the forgotten old, plus a little of my own.

Anything is possible. ctr + c ctrl+v

What if a miracle happens?

using System.Collections.Generic;
using System.Text;
using UnityEngine;
using System.Linq;

public class SelectionUnits7 : MonoBehaviour
{
    bool isSelecting = false;
    Vector3 mousePosition1;
    private bool _debug = true;

    public static List<GameObject> selectedObjects = new List<GameObject>();
    GameObject edenicy;

    //----------------------------------------------------------------

    static Texture2D _whiteTexture;
    static Texture2D WhiteTexture
    {
        get
        {
            if (_whiteTexture == null)
            {
                _whiteTexture = new Texture2D(1, 1);
                _whiteTexture.SetPixel(0, 0, Color.white);
                _whiteTexture.Apply();
            }

            return _whiteTexture;
        }
    }

     static void DrawScreenRect(Rect rect, Color color)
    {
        GUI.color = color;
        GUI.DrawTexture(rect, WhiteTexture);
        GUI.color = Color.white;
    }

     static void DrawScreenRectBorder(Rect rect, float thickness, Color color)
    {
        // Top
        DrawScreenRect(new Rect(rect.xMin, rect.yMin, rect.width, thickness), color);
        // Left
        DrawScreenRect(new Rect(rect.xMin, rect.yMin, thickness, rect.height), color);
        // Right
        DrawScreenRect(new Rect(rect.xMax - thickness, rect.yMin, thickness, rect.height), color);
        // Bottom
        DrawScreenRect(new Rect(rect.xMin, rect.yMax - thickness, rect.width, thickness), color);
    }

    static Rect GetScreenRect(Vector3 screenPosition1, Vector3 screenPosition2)
    {
        // Move origin from bottom left to top left
        screenPosition1.y = Screen.height - screenPosition1.y;
        screenPosition2.y = Screen.height - screenPosition2.y;
        // Calculate corners
        var topLeft = Vector3.Min(screenPosition1, screenPosition2);
        var bottomRight = Vector3.Max(screenPosition1, screenPosition2);
        // Create Rect
        return Rect.MinMaxRect(topLeft.x, topLeft.y, bottomRight.x, bottomRight.y);
    }

    static Bounds GetViewportBounds(Camera camera, Vector3 screenPosition1, Vector3 screenPosition2)
    {
        var v1 = Camera.main.ScreenToViewportPoint(screenPosition1);
        var v2 = Camera.main.ScreenToViewportPoint(screenPosition2);
        var min = Vector3.Min(v1, v2);
        var max = Vector3.Max(v1, v2);
        min.z = camera.nearClipPlane;
        max.z = camera.farClipPlane;

        var bounds = new Bounds();
        bounds.SetMinMax(min, max);
        return bounds;
    }

    //-----------------------------------------------------------------





    void Update()
    {

        SelectRect();

    }


    void SelectRect()
    {
        // If we press the left mouse button, begin selection and remember the location of the mouse
        // Если мы нажмем левую кнопку мыши, начнем выделение и запомним положение мыши
        if (Input.GetMouseButtonDown(0))
        {
            if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift))
            {
                goto LinkSpec;
            }
            selectedObjects.Clear();
                                                                                  
            GameObject[] selectableObject1 = GameObject.FindGameObjectsWithTag("Unit");
                   
            for (var st1 = 0; st1 < GameObject.FindGameObjectsWithTag("Unit").Length; st1++)
            {

                if (selectableObject1[st1].transform.GetChild(0).gameObject.activeSelf == true)
                {
                    selectableObject1[st1].transform.GetChild(0).gameObject.SetActive(false);
                }

            }

           LinkSpec:
            isSelecting = true;
            mousePosition1 = Input.mousePosition;


            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);            //получим координаты мышки
            RaycastHit hit;                                                         //Объявим структуру, из которой будем брать данные
            if (Physics.Raycast(ray, out hit, 10000))                                 //возвращает true если сталкивается с чем либо
            {
                if (_debug) Debug.DrawLine(ray.origin, hit.point);                  //покажем линией на выделяемый объект.

                if (hit.collider.gameObject.tag == "Unit") // Разрешаем помечать объекты только с этим тегом
                {
                    edenicy = hit.collider.gameObject;
                    if (edenicy.gameObject.tag == "Unit")
                    {
                        selectedObjects.Add(edenicy);
                        if( selectedObjects.Count>1)
                        {
                            List<GameObject> unique = selectedObjects.Distinct().ToList();
                            selectedObjects = unique;
                           
                        }

                    }

                    hit.collider.transform.GetChild(0).gameObject.SetActive(true);
                }
            }


        }
        //-------------------------------------------------------------

        // If we let go of the left mouse button, end selection
        // Если мы отпустим левую кнопку мыши, закончим выделение
        if (Input.GetMouseButtonUp(0))
        {


           // List<GameObject> specSpisok = new List<GameObject>();
            GameObject[] selectableObject1 = GameObject.FindGameObjectsWithTag("Unit");

            for (var st1 = 0; st1 < GameObject.FindGameObjectsWithTag("Unit").Length; st1++)

            {
                if (IsWithinSelectionBounds(selectableObject1[st1].gameObject))
                {
                    //specSpisok.Add(selectableObject1[st1]);
                    selectedObjects.Add(selectableObject1[st1]);

                }
            }
           

            //if (IsWithinSelectionBounds(edenicy.gameObject))
            //{
            //   
            //    selectedObjects = specSpisok;
            //}
            List<GameObject> unique = selectedObjects.Distinct().ToList();
            selectedObjects = unique;

            var sb = new StringBuilder();
            sb.AppendLine(string.Format("Selecting [{0}] Units", selectedObjects.Count));
            foreach (var selectedObject in selectedObjects)
                sb.AppendLine("-> " + selectedObject.gameObject.name);
            Debug.Log(sb.ToString());
          

            isSelecting = false;
        }

        //--------------------------------------------------------------
        // Highlight all objects within the selection box
        // Выделяем все объекты в рамке выбора
        if (isSelecting)
        {

            GameObject[] selectableObject1 = GameObject.FindGameObjectsWithTag("Unit");

            for (var st1 = 0; st1 < GameObject.FindGameObjectsWithTag("Unit").Length; st1++)

            {


                if (IsWithinSelectionBounds(selectableObject1[st1].gameObject) )
                {
                    if (

                       selectableObject1[st1].transform.GetChild(0).gameObject.activeSelf == false
                        )

                    {
                        selectableObject1[st1].transform.GetChild(0).gameObject.SetActive(true);

                    }
                }
                else
                {
                    if (
                     selectableObject1[st1].transform.GetChild(0).gameObject.activeSelf == true
                     & Input.GetKey(KeyCode.LeftShift) == false
                     && Input.GetKey(KeyCode.RightShift) == false

                       )
                    {
                        selectableObject1[st1].transform.GetChild(0).gameObject.SetActive(false);
                        if (edenicy)
                        {
                            edenicy.transform.GetChild(0).gameObject.SetActive(true);
                        }
                    }
                }
            }
        }
       


    }





    public bool IsWithinSelectionBounds(GameObject gameObject)
    {
        if (!isSelecting)
            return false;

        var camera = Camera.main;
        var viewportBounds = GetViewportBounds(camera, mousePosition1, Input.mousePosition);
        return viewportBounds.Contains(camera.WorldToViewportPoint(gameObject.transform.position));
    }

    void OnGUI()
    {
        if (isSelecting)
        {
            // Create a rect from both mouse positions
            var rect = GetScreenRect(mousePosition1, Input.mousePosition);
            //DrawScreenRect(rect, new Color(0.5f, 1f, 0.4f, 0.2f));
            DrawScreenRectBorder(rect, 2, new Color(0.1882353f, 0.3241227f, 0.7254902f));
        }
    }




}

Hangs on any object on the stage.More details on the links.