Оптимизация кода

Программирование на Юнити.

Оптимизация кода

Сообщение ninrez 02 июл 2021, 18:10

Здравствуйте! Подскажите, пожалуйста, как в данном случае можно избавиться от elseif?
https://pastebin.com/5xh4N6v1
ninrez
UNец
 
Сообщения: 11
Зарегистрирован: 08 дек 2020, 08:54

Re: Оптимизация кода

Сообщение 1max1 02 июл 2021, 18:38

Никак))
Код разный, каждый объект использует свой код, объединить их нельзя так как у них мало общего. Могу предложить 1 вариант, но он не сделает код меньше, просто разобьет его на более мелкие части.
Ты можешь для каждого объекта создать общий класс и добавить туда реализацию методов, к примеру:

Синтаксис:
Используется csharp
using UnityEngine;

abstract class InteractiveObject : MonoBehaviour
{
    public abstract void Use();
}

class Door : InteractiveObject
{
    public override void Use()
    {
        // что-то делаем с дверью
    }
}

class Item : InteractiveObject
{
    public override void Use()
    {
        // что-то делаем с предметом
    }
}

После этого создаешь дочерние классы от InteractiveObject для своих объектов, пишешь реализацию для каждого, потом вешаешь эти скрипты на все свои объекты. В своем скрипте после рейкаста берешь у объекта компонент InteractiveObject и вызываешь нужный метод. У каждого объекта будет вызван свой метод Use. Кода меньше не станет, но такой простыни как у тебя больше не будет. По сути, твой супер-класс, который делает всё, теперь будет отвечать только за рейкаст.
Аватара пользователя
1max1
Адепт
 
Сообщения: 5505
Зарегистрирован: 28 июн 2017, 10:51

Re: Оптимизация кода

Сообщение samana 02 июл 2021, 19:07

Или разбить все ветвления на отдельные методы. Создать словарь команд, где ключ - строкаТег, а значение - метод.
Синтаксис:
Используется csharp
private Dictionary<string, Action<RaycastHit>> _commands;

private void Start()
{
    _commands = new Dictionary<string, Action<RaycastHit>>();
    _commands.Add("StartDoor", StartDoor);
    _commands.Add("NidDoor", NidDoor);
    _commands.Add("ClosedDoor", ClosedDoor);
    _commands.Add("StartKey", StartKey);
    _commands.Add("StartBook", StartBook);
    _commands.Add("StartTurnOnLight", StartTurnOnLight);
    _commands.Add("SecoundFloorTOL", SecoundFloorTOL);
    _commands.Add("FirstFloorRestRoom", FirstFloorRestRoom);
    _commands.Add("FlashLight", FlashLight);
    _commands.Add("Battery", Battery);
    _commands.Add("ShellR1", ShellR1);
    _commands.Add("ShellL1", ShellL1);
}


Это вас не спасёт, так как код действительно делает слишком много всего. Но зато метод Update станет чище.

Синтаксис:
Используется csharp
private void Update()
{
    RaycastHit hit;
    Vector3 fwd = transform.TransformDirection(Vector3.forward);
    int mask = 1 << LayerMask.NameToLayer(nameOfMask) | layerMask.value;

    if (Physics.Raycast(transform.position, fwd, out hit, rayLenght, mask))
    {
        string tag = hit.collider.tag;

        if (_commands.ContainsKey(tag))
            _commands[tag].Invoke(hit);
    }
}


здесь всё вместе с методами
Синтаксис:
Используется csharp
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Test : MonoBehaviour
{

    private Dictionary<string, Action<RaycastHit>> _commands;

    private void Start()
    {
        _commands = new Dictionary<string, Action<RaycastHit>>();
        _commands.Add("StartDoor", StartDoor);
        _commands.Add("NidDoor", NidDoor);
        _commands.Add("ClosedDoor", ClosedDoor);
        _commands.Add("StartKey", StartKey);
        _commands.Add("StartBook", StartBook);
        _commands.Add("StartTurnOnLight", StartTurnOnLight);
        _commands.Add("SecoundFloorTOL", SecoundFloorTOL);
        _commands.Add("FirstFloorRestRoom", FirstFloorRestRoom);
        _commands.Add("FlashLight", FlashLight);
        _commands.Add("Battery", Battery);
        _commands.Add("ShellR1", ShellR1);
        _commands.Add("ShellL1", ShellL1);
    }

    private void Update()
    {
        RaycastHit hit;
        Vector3 fwd = transform.TransformDirection(Vector3.forward);
        int mask = 1 << LayerMask.NameToLayer(nameOfMask) | layerMask.value;

        if (Physics.Raycast(transform.position, fwd, out hit, rayLenght, mask))
        {
            string tag = hit.collider.tag;

            if (_commands.ContainsKey(tag))
                _commands[tag].Invoke(hit);
        }
    }

    private void ShellL1(RaycastHit hit)
    {
        OpenShell("ShellLO", "ShellLC", hit);
    }

    private void ShellR1(RaycastHit hit)
    {
        OpenShell("ShellRO", "ShellRC", hit);
    }

    private void Battery(RaycastHit hit)
    {
        VisibleChrosshair();
        if (Input.GetKeyDown(interactingKey))
        {
            Destroy(hit.collider.gameObject);
            scr_Torch.countBattery++;
        }
    }

    private void FlashLight(RaycastHit hit)
    {
        VisibleChrosshair();
        if (Input.GetKeyDown(interactingKey))
        {
            Destroy(hit.collider.gameObject);
            haveFlash = true;
        }
    }

    private void FirstFloorRestRoom(RaycastHit hit)
    {
        VisibleChrosshair();
        if (Input.GetKeyDown(interactingKey))
        {
            scr_TurnOnLight.TurnOnLight(firstFloorRR, scr_TurnOnLight.firstRestRoom);
            firstFloorRR = !firstFloorRR;
        }
    }

    private void SecoundFloorTOL(RaycastHit hit)
    {
        VisibleChrosshair();
        if (Input.GetKeyDown(interactingKey))
        {
            scr_TurnOnLight.TurnOnLight(secoundF, scr_TurnOnLight.secoundF);
            secoundF = !secoundF;
        }
    }

    private void StartTurnOnLight(RaycastHit hit)
    {
        VisibleChrosshair();
        if (Input.GetKeyDown(interactingKey))
        {
            scr_TurnOnLight.TurnOnLight(startLight, scr_TurnOnLight.start);
            startLight = !startLight;
        }
        //TurnOnLight(startLight, startLights);
    }

    private void StartBook(RaycastHit hit)
    {
        VisibleChrosshair();
        BookOpening(0);
    }

    private void StartKey(RaycastHit hit)
    {
        VisibleChrosshair();
        if (Input.GetKeyDown(interactingKey))
        {
            haveStartKey = true;
            Destroy(hit.collider.gameObject);
        }
    }

    private void ClosedDoor(RaycastHit hit)
    {
        VisibleChrosshair();
        if (Input.GetKeyDown(interactingKey))
        {
            subtitles.text = "Закрыто";
            scr_Main.ShowSubtitles();
        }
    }

    private void NidDoor(RaycastHit hit)
    {
        VisibleChrosshair();
        scr_Door = hit.collider.gameObject.GetComponent<SCR_Door>();
        if (Input.GetKeyDown(interactingKey))
            scr_Door.PlayAnimation();
    }

    private void StartDoor(RaycastHit hit)
    {
        if (!doOnce)
        {
            scr_Door = hit.collider.gameObject.GetComponent<SCR_Door>();
            isChrosshairChange(true);
        }
        if (haveStartKey)
        {
            if (Input.GetKeyDown(interactingKey))
                scr_Door.PlayAnimation();
        }
        else
            if (Input.GetKeyDown(interactingKey))
        {
            subtitles.text = "Закрыто";
            scr_Main.ShowSubtitles();
        }
    }
}
 
Последний раз редактировалось samana 02 июл 2021, 19:30, всего редактировалось 1 раз.
Аватара пользователя
samana
Адепт
 
Сообщения: 4738
Зарегистрирован: 21 фев 2015, 13:00
Откуда: Днепропетровск

Re: Оптимизация кода

Сообщение ninrez 02 июл 2021, 19:12

Спасибо большое за советы!
ninrez
UNец
 
Сообщения: 11
Зарегистрирован: 08 дек 2020, 08:54


Вернуться в Скрипты

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4