0
\$\begingroup\$

I'm making a 2D game using Unity and I want to implement cutscenes that change over at certain lines.

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

public class CgChanger : MonoBehaviour
{
   public Image imageToChange; // Reference to the UI Image component
    public Sprite[] sprites; // Array of sprites to cycle through`

    private int currentSpriteIndex = 0;

    void Start()
    {
        if (imageToChange == null || sprites == null || sprites.Length < 6)
        {
            Debug.LogError("ImageToChange or Sprites are not assigned or Sprites array has fewer than 6 elements.");
            return;
        }

        // Initialize with the first sprite
        imageToChange.sprite = sprites[currentSpriteIndex];
    }

    void Update()
    {
        // Check if the left mouse button is pressed
        if (Input.GetMouseButtonDown(0))
        {
            // Move to the next sprite in the array
            currentSpriteIndex++;

            // Ensure we do not exceed the array bounds
            if (currentSpriteIndex >= sprites.Length)
            {
                currentSpriteIndex = 0; // Reset to the first sprite if the end is reached
            }

            // Change the image sprite to the next one in the array
            imageToChange.sprite = sprites[currentSpriteIndex];
        }
    }
}

This is the code I have currently, but it's flawed and I'm not sure how to fix it. I don't want it to change when the person clicks down on the mouse like it is with the text, and how it is with the images currently. That messes up the pacing if someone clicks more than once per line. How would I go about changing this?

Edit: I realize I wasn't as clear as I should have been with what I want. i have a certain amount of cutscene images that I want to stay on screen while certain lines are displayed, before switching to another image. If you've ever seen the cutscenes from the game Danganronpa, it's a bit like that

\$\endgroup\$
2
  • \$\begingroup\$ Do you want to change the full scene or are you asking how to change the sprite/ image with your code but preventing the double click? \$\endgroup\$ Commented Oct 14 at 6:25
  • \$\begingroup\$ The "I don't want..." part is clear. What we're missing is what you DO want this script to do instead. What are the "lines" that should change over the cutscene? How do you designate which "certain" lines should or should not trigger this? Are the lines swapped on click, or do they play out over a duration of time / with delays in between? \$\endgroup\$ Commented Oct 14 at 11:51

2 Answers 2

0
\$\begingroup\$

You can switch the cutscene based on any user event or with time delay (use Coroutines or Update or Async). For example simple Delay logic:

[SerializedField]
float[] _delays;

float time=0;

 void Update()
    {
        time+=Time.deltaTime;
        // Check if the left mouse button is pressed
        if (time>_delays[currentSpriteIndex])
        {
            // Move to the next sprite in the array
            currentSpriteIndex++;
            time=0;
            // Ensure we do not exceed the array bounds
            if (currentSpriteIndex >= sprites.Length)
            {
                currentSpriteIndex = 0; // Reset to the first sprite if the end is reached
            }

            // Change the image sprite to the next one in the array
            imageToChange.sprite = sprites[currentSpriteIndex];
        }
    }

Where _delays is time in seconds between all cutscenes (_delays[0] time passed to show sprites[1]).

\$\endgroup\$
0
\$\begingroup\$

If I understand you correctly, you are trying to create a kind of visual novel system, where lines of text are accompanied by images.

In that case it would make sense to declare a struct type that contains both the line and (references to the) image(s) you want that line of text to be accompanied by. So you have both pieces of information together and handle them as one piece of data.

Example:

public class Dialog : MonoBehaviour

    [Serializable]
    struct DialogLine {
        public string text;
        public Sprite image;
    }

    public DialogLine[] lines;

   [...]

    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            currentLineIndex++;
            yourUiImage.sprite = line[currentLineIndex].image;
            yourUiText.text = line[currentLineIndex].text;
        }
   }
}

Due to the [Serializable] attribute, you will get an automatic editor for your lines array in the inspector of this game object. So you can write your dialogue directly in the inspector by adding new elements to that array, entering text and assigning sprite assets via drag&drop.

This might be sufficient for a small game or prototype, or one where the cutscenes remain linear and simple. But if you intent to create a more ambitioned project, then you might want to consider how you can streamline your workflow further. Especially when you need more advanced things like branching dialogues, variables embedded in text or programming logic embedded within dialogues. In that case the solution I presented here might quickly turn ugly.

One more expandable solution would be to read the lines from a text file in a scripting language. You could invent and implement your own language for that (been there, done that, went temporarily insane), but you will probably save a lot of time and sanity by using an existing solutions for that like Ink or Yarnspinner. Or you could go for a complete kitchen-sink-included visual novel system like Naninovel.

\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.