Unity中的图片,只显示最近的图片

问题描述 投票:0回答:2

我在 Unity 中创建了一个游戏,玩家可以用宝丽来相机拍照,宝丽来会掉到地上。玩家可以从这里拿起它们并查看它们。

我可以拍照并与宝丽来互动,现在唯一的问题是地面上的所有宝丽来都显示相同的图像。显示的是最近拍摄的图像。

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

public class PhotoCapture:MonoBehaviour {
    [Header("Photo Taker")]
    [SerializeField] public Image photoDisplayArea;
    [SerializeField] public GameObject photoFrame;

    [Header("Flash Effect")]    
    [SerializeField] private GameObject cameraFlash;
    [SerializeField] private float flashTime;

    private Texture2D screenCapture;
    public static bool viewingPhoto = false;

    // All text GUI needs to be in this parent object
    [Header("GUI")]
    [SerializeField] private GameObject GUI;

    [Header("Polaroid GameObject")]
    [SerializeField] private GameObject itemPolaroid;

    [Header("Controls")]
    //[SerializeField] private KeyCode useCamera = KeyCode.Mouse0;
    [SerializeField] private KeyCode closePicture = KeyCode.Mouse1;

    // Raycast
    private RaycastHit hitObject;
    private bool itemObject = false;

    // Start is called before the first frame update
    void Start() {
        screenCapture = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false);
    }

    // Update is called once per frame
    void Update() {
        if(Input.GetKeyDown(PlayerActions.useCameraButton) && ItemCamera.canUseCamera && !viewingPhoto) {
            StartCoroutine(CapturePhoto());
        }

        itemObject = Physics.Raycast(transform.position, transform.forward, out hitObject, 6f);
        if(!viewingPhoto && Input.GetKeyDown(PlayerActions.actionButton) && itemObject && hitObject.collider.gameObject.CompareTag("Polaroid")) {
            ShowPhoto();
        }

        if(viewingPhoto && Input.GetKeyDown(closePicture)) {
            RemovePhoto();
        }
    }
    /// <summary>
    /// Increases light intensity on object - CameraFlash
    /// </summary>
    /// <returns></returns>
    private IEnumerator CameraFlashEffect() {
        cameraFlash.SetActive(true);
        yield return new WaitForSeconds(flashTime);
        cameraFlash.SetActive(false);
    }

    private IEnumerator CapturePhoto() {
        // CameraUI set false
        GUI.SetActive(false);

        yield return new WaitForEndOfFrame();

        Rect regionToRead = new(0, 0, Screen.width, Screen.height);
        screenCapture.ReadPixels(regionToRead, 0, 0, false);
        screenCapture.Apply();

        // Makes a sprite of the screenshot and places it in PhotoDisplayArea in ItemPolaroidObject
        Sprite photoSprite = Sprite.Create(screenCapture, new Rect(0.0f, 0.0f, screenCapture.width, screenCapture.height), new Vector2(0.5f, 0.5f), 100.0f);
        photoDisplayArea.sprite = photoSprite;

        StartCoroutine(CameraFlashEffect());
        GUI.SetActive(true);
        SpawnItemPolaroid();
    }

    public void ShowPhoto() {
        viewingPhoto = true;
        GUI.SetActive(false);
        // Sets PhotoFrameBG (Blank canvas) in ItemPolaroidObject to true
        photoFrame.SetActive(true);
    }

    private void RemovePhoto() {
        viewingPhoto = false;
        photoFrame.SetActive(false);
        GUI.SetActive(true);
    }

    // Bug - becomes a clone of original object and change with the original
    private void SpawnItemPolaroid() {
        GameObject newPolaroid = Instantiate(itemPolaroid, new Vector3(Random.Range(FirstPersonController.characterController.transform.position.x - 0.5f, FirstPersonController.characterController.transform.position.x + 0.5f), Random.Range(FirstPersonController.characterController.transform.position.y + 0.5f, FirstPersonController.characterController.transform.position.y + 1.5f), Random.Range(FirstPersonController.characterController.transform.position.z - 0.5f, FirstPersonController.characterController.transform.position.z + 0.5f)), Quaternion.identity);

    }
}

我已尝试将 photoDisplayArea 和 photoFrame 设置为每个新克隆,但它不起作用。

c# unity3d
2个回答
0
投票

您只在启动方法中分配给“screenCapture”,因此当您使用 Sprite.Create 创建新图像时,您最终会引用相同的 Texture2D 实例,然后 Unity 使用该实例为所有照片绘制游戏中的纹理。

解决方案:

要解决此问题,您可以简单地在“CapturePhoto()”中创建一个新的 Texture2D 并将其分配给“screenCapture”。


0
投票

最简单的解决方案是每次要截屏时创建一个新纹理。

screenCapture = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false);
screenCapture.ReadPixels(regionToRead, 0, 0, false);
screenCapture.Apply();

太多纹理会消耗太多内存,因此如果您的游戏经常崩溃,请考虑将纹理保存到文件读取它们当您需要将它们显示给玩家时

© www.soinside.com 2019 - 2024. All rights reserved.