Unity 电路解密小游戏实现思路

实现效果

效果展示视频
项目Github
在这里插入图片描述

功能需求

点击电线组件可以旋转,连接电池首尾游戏结束(该Demo还要连通特殊组件),连通后线路会亮起来(该Demo只要和正极相连的线路就会亮,Demo的亮是图片颜色变化和Unity光照,这里就写图片的颜色变化,思路是差不多的)。不需要记录正确路线的所有电线组件的正确方向,将电路组件做成prefab后,可以由策划自由放置,判断是否连接正确由组件之间的自行判断。

实现思路

为每个电线组件添加接口Trigger,点击组件后组件进行旋转,将接口触发到的线路引用添加进来,将离开的线路引用删除,然后发送事件,重置所有让电池开始从正极的电线开始递归调用显示。

实现过程

创建电线组件

创建一个空物体命名为Line_A并添加Tag为Line,在其下创建俩个空物体,一个命名为Images用来存放图片,一个命名为CheckPoints用来存放检测点并为其子物体添加Tag为CheckPoint。
在这里插入图片描述
给Line_添加BoxCollider2D,调整好大小覆盖整个线路,这个Collider是用来检测鼠标的点击旋转的。再给Points下的物体添加BoxCollider2D,并勾选is Trigger,再添加RigidBody2D,并设计BodyType为Kinematic,这个是用来判断线路之间的连接情况的。

在这里插入图片描述
给Line_A添加Line.cs脚本,并把图片拖拽上去

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Rendering.Universal;

public class Line : MonoBehaviour
{
    
    
    public bool isPower;//用来判断该线路组件是否处于通电状态
    public List<GameObject> nextLines = new List<GameObject>();//连接线路的引用
    public SpriteRenderer spriteRenderer;//图片

    public void Rotate()
    {
    
    
        this.transform.Rotate(0, 0, -90);
    }
    public void AddNextLine(GameObject line)
    {
    
    
        nextLines.Add(line);
    }
    public void DeleteNextLine(GameObject line)
    {
    
    
        nextLines.Remove(line);
    }

    /// <summary>
    /// 通电递归
    /// </summary>
    public void Power()
    {
    
    
        Debug.Log(this.transform.name + "通电了");
        isPower = true;
        // 通电效果
        SetLuminance(true);
        //给连接的线路通电
        foreach (GameObject nextLine in nextLines)
        {
    
    
            var line = nextLine.GetComponent<Line>();
            if (!line.isPower)
            {
    
    
                line.Power();
            }
        }
    }

    /// <summary>
    /// 重置状态
    /// </summary>
    public void ResetStatic()
    {
    
    
        isPower = false;
        SetLuminance(false);
    }
    /// <summary>
    /// 通电后颜色变化
    /// </summary>
    /// <param name="p">true变红/false变会原来的颜色</param>
    public void SetLuminance(bool p)
    {
    
    
        if (p)
        {
    
    
            spriteRenderer.color = new Color32(240, 124, 130, 255);
        }
        else
        {
    
    
            spriteRenderer.color = new Color(1f, 1f, 1f, 1f);
        }

    }
}

给CheckPoint添加CheckPoint.cs,并拖拽父对象的引用

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

public class CheckPoint : MonoBehaviour
{
    
    
    public Line line;
    private void OnTriggerEnter2D(Collider2D other)
    {
    
    
        if (other.CompareTag("CheckPoint"))
        {
    
    
            //Debug.Log("连接到线路");
            line.AddNextLine(other.transform.parent.parent.gameObject);
        }
    }
    private void OnTriggerExit2D(Collider2D other)
    {
    
    
        if (other.CompareTag("CheckPoint"))
        {
    
    
            //Debug.Log("断开线路");
          line.DeleteNextLine(other.transform.parent.parent.gameObject);
        }
    }
}

同理,我们可以再设计更多线路预制体
在这里插入图片描述
在这里插入图片描述

创建电池组件

同理电线的制作
在这里插入图片描述
为Battery添加Battery.cs

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

public class Battery : MonoBehaviour
{
    
    
    public GameObject outLine;//正极连接的线
    public GameObject inLine;//负极连接的线

    /// <summary>
    /// 开始通电
    /// </summary>
    public void StartPower()
    {
    
    
        if (outLine != null)
        {
    
    
            //Debug.Log("电池开始通电");
            outLine.GetComponent<Line>().Power();
        }
    }
}

把Points下的对象的CheckPoint.cs换成InPole.cs和OutPole.cs

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

/// <summary>
/// 负极
/// </summary>
public class InPole : MonoBehaviour
{
    
    
    public Battery battery;
    private void OnTriggerEnter2D(Collider2D other)
    {
    
    
        if (other.CompareTag("CheckPoint"))
        {
    
    
            //Debug.Log("连接到线路");
            battery.inLine = other.transform.parent.parent.gameObject;
        }
    }
    private void OnTriggerExit2D(Collider2D other)
    {
    
    
        if (other.CompareTag("CheckPoint"))
        {
    
    
            //Debug.Log("断开线路");
            battery.inLine = null;
        }
    }
}

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

/// <summary>
/// 正极
/// </summary>
public class OutPole : MonoBehaviour
{
    
    
    public Battery battery;
    private void OnTriggerEnter2D(Collider2D other)
    {
    
    
        if (other.CompareTag("CheckPoint"))
        {
    
    
            //Debug.Log("连接到线路");
            battery.outLine = other.transform.parent.parent.gameObject;
        }
    }
    private void OnTriggerExit2D(Collider2D other)
    {
    
    
        if (other.CompareTag("CheckPoint"))
        {
    
    
            //Debug.Log("断开线路");
            battery.outLine = null;
        }
    }
}

鼠标点击管理类

在场景中创建空物体命名为Cursor Manager,添加CursorManager.cs单例类,鼠标点击后检测周围的碰撞体,如果Tag是Line,则调用它的旋转方法,
然后发送让关卡管理类指挥通电。

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

/// <summary>
/// 管理鼠标点击
/// </summary>
public class CursorManager : Singleton<CursorManager>
{
    
    
    private Vector3 mouseWorldPos =>
    Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 0));

    private void Update()
    {
    
    
        if (Input.GetMouseButtonDown(0))
        {
    
    
            //检测鼠标互动情况
            ClickAction(ObjectAtMousePosition().gameObject);
        }
    }
    private void ClickAction(GameObject clickObject)
    {
    
    
        if (clickObject != null)
        {
    
    
            switch (clickObject.tag)
            {
    
    
                case "Line":
                    var line = clickObject.GetComponent<Line>();
                    line?.Rotate();
                    LevelManager.Instance.StartPowerCommand();
                    break;
            }
        }
    }
    /// <summary>
    /// 检测鼠标点击范围的碰撞体
    /// </summary>
    /// <returns></returns>
    private Collider2D ObjectAtMousePosition()
    {
    
    
        return Physics2D.OverlapPoint(mouseWorldPos);
    }
}

单例类

using System;
using UnityEngine;

public class Singleton<T> : MonoBehaviour where T : Singleton<T>
{
    
    
    private static T instance;

    public static T Instance
    {
    
    
        get {
    
     return instance; }
    }

    protected void Awake()
    {
    
    
        if (instance != null)
            Destroy(gameObject);
        else
        {
    
    
            instance = (T) this;
        }
    }

    public static bool IsInitialized
    {
    
    
        get {
    
     return instance != null; }
    }

    protected virtual void OnDestroy()
    {
    
    
        if (instance == this)
        {
    
    
            instance = null;
        }
    }
}

游戏管理类

在场景中创建空物体命名为Level Manager,添加LevelManager.cs单例类

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

public class LevelManager : Singleton<LevelManager>
{
    
    
    public Battery battery;
    [Header("场景中存在的线")]
    public GameObject[] lines;
    private void Start()
    {
    
    
        lines = GameObject.FindGameObjectsWithTag("Line");
    }
    public void StartPowerCommand()
    {
    
    
        //重置所有线的状态
        for (int i = 0; i < lines.Length; i++)
        {
    
    
            lines[i].GetComponent<Line>().ResetStatic();
        }

        //这里需要延迟调用一下,因为通过OnTrigger添加对象会有延迟
        Invoke("StartPower", 0.5f);

        //这里需要延迟调运一下,因为电路的递归需要点时间
        Invoke("isGameOver", 0.5f);
    }
    private void StartPower()
    {
    
    
        battery.StartPower();
    }
	
    private void isGameOver()
    {
    
    
        GameObject gameObject = battery.inLine;
        if (gameObject != null)
        {
    
    
            if (gameObject.GetComponent<Line>().isPower) 
                GameOver();
        }
    }
    private void GameOver()
    {
    
    
        Debug.Log("GameOver");
    }
}

关卡设计

把所有东西添加成预制体,就可以自由地开始关卡设计了
按住Ctrl可以控制移动距离,还可以自己设置距离
在这里插入图片描述
在这里插入图片描述

总结

多喝热水、少熬夜,心情美美的,一切问题都会应难而解。

猜你喜欢

转载自blog.csdn.net/qq_51491918/article/details/127474783