首页 > 解决方案 > 为什么当我按住轻按时这不会改变填充量?

问题描述

我正在尝试设置按住拾取动画。按下左键时,此代码应更改精灵的填充量,但事实并非如此。基本上,当玩家看到一个可交互的对象时,会弹出一个窗口,告诉他们按住字母 E。当他们在字母 E 周围填充进度条时。但是当我尝试使用代码更改进度条的填充量时. 它只是没有做任何事情。我在代码中留下了一些其他解决方案作为注释,以表明我尝试了我所知道的一切。我自己对团结还很陌生,这真的是我第一次诚实地说。

我试过达到

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




public class Interaction : MonoBehaviour
{
    [SerializeField]
    private new Camera camera; 
    [SerializeField]
    private float pickupTime = 10f; 
    [SerializeField]
    private Image pickProgressImage;
    [SerializeField]
    private RectTransform pickupImageRoot;
    [SerializeField]
    private LayerMask layerMask; 
    [SerializeField]
    private TextMeshProUGUI itemNameText; 
    private Item itemBeingPickedUp; 
    //private float currentPickupTimerElasped;

    private float TimeTest;



    private void Update()
    {
        SelectItemBeingInteractedWithFromRay();
        if  (HasItemTargetted())
        {
            pickupImageRoot.gameObject.SetActive(true);
            if (Input.GetMouseButtonDown(0))
            {
                //TimeTest += (float)0.1; 
                pickProgressImage.fillAmount += TimeTest;
                //IncrementPickupProgressandTryComplete();

            }
            else;
            {
                //currentPickupTimerElasped = 0f;
                TimeTest = 0f;
            }
             UpdatePickupProgressImage();
        }
        else
        {
            pickupImageRoot.gameObject.SetActive(false);
            //currentPickupTimerElasped = 0f;
            TimeTest = 0f;
        }



    }
    private bool HasItemTargetted()
    {
        return itemBeingPickedUp != null;
    }
    private void IncrementPickupProgressandTryComplete()
    {
        TimeTest += (float)0.1; 
        //currentPickupTimerElasped = currentPickupTimerElasped + Time.deltaTime;
       //if (currentPickupTimerElasped >= pickupTime)
       // {
       //     itemBeingPickedUp = null;
            //Start MiniGame
      //  }

    }

    private void UpdatePickupProgressImage()
    {
        //float pct = currentPickupTimerElasped / pickupTime;
        //ProgressBox.fillAmount += pct;
        pickProgressImage.fillAmount += TimeTest;

    }
    private void SelectItemBeingInteractedWithFromRay()
    {
        Ray ray = camera.ViewportPointToRay(Vector3.one / 8f);

        Debug.DrawRay(ray.origin,ray.direction * 8f, Color.red); 

        RaycastHit hitInfo;
        if (Physics.Raycast(ray, out hitInfo, 8f, layerMask))
        {
            var hitItem = hitInfo.collider.GetComponent<Item>();

            if (hitItem == null)

            {
                itemBeingPickedUp = null;
            }
            else if (hitItem != null && hitItem != itemBeingPickedUp)
            {
                itemBeingPickedUp = hitItem; 
                itemNameText.text = "Pickup" + itemBeingPickedUp.gameObject.name;
            }


        }
        else
        {
            itemBeingPickedUp = null;
        }
    }
}

它应该改变填充量

标签: unity3d

解决方案


Input.GetMouseButtonDowntrue一个帧中-按钮按下的帧。

true在用户按下给定鼠标按钮的帧期间返回。

在那false之后的框架中!


您可能更愿意使用的是Input.GetMouseButton

返回给定的鼠标按钮是否被按住。

if(Input.GetMouseButton(0))

只要true按钮保持按下状态


但是,我不太了解您对TimeTest这里的其他变量和方法的使用。可能只是0?你pickProgressImage.fillAmount在两个不同的地方增加,而且TimeTest..这让我有点困惑。而且你的一些方法是相当多余的。

您不需要进一步的变量来检查所需的时间是否已经过去......只需使用比较值来检查pickProgressImage.fillAmount自身。Mathf.Approximatelyfloat

同样对于增量,您不应该使用固定值0.1f(这就是您声明浮点值的方式),而是使用Time.deltaTime以将其他与帧速率相关的增量转换为与帧速率无关的“每秒增量”值。

您也不需要检查 if itemBeingPickedUpis set or的方法null:由于您的Itemis aMonoBehaviour继承自UnityEngine.Object您,因此可以使用 it'sbool运算符来检查它的存在。

// How long shall filling from 0 to 1 take in seconds?
// Adjust in the Inspector
[SerializeField] private float pickupTime = 1;

private void Update()
{
    SelectItemBeingInteractedWithFromRay();

    // You don't need a method for this
    // all types inherited from UnityEngine.Object 
    // Have a bool operator which equals a != null
    if (itemBeingPickedUp)
    {
        pickupImageRoot.gameObject.SetActive(true);
        // initially reset the fill
        pickProgressImage.fillAmount = 0
        if (Input.GetMouseButton(0))
        {
            // Use Time.deltaTime in order to convert the otherwise
            // FRAME WISE increment to rather an increment per seconds
            pickProgressImage.fillAmount += Time.deltaTime * pickupTime;

            // You don't need additional methods or variables
            // for checking if enough time passed
            // simply use the fill itself as check
            if(Mathf.Approximately(pickProgressImage.fillAmount, 1))
            {
                // FULLY FILLED -> DO SOMETHING
            }
        }
        else;
        {
            // Reset the fill itself not only your other variables
            pickProgressImage.fillAmount = 0;
        }
    }
    else
    {
        pickupImageRoot.gameObject.SetActive(false);
        // Reset the fill itself not only your other variables
        pickProgressImage.fillAmount = 0;
    }
}

作为口味问题,我实际上也会将返回类型设置为SelectItemBeingInteractedWithFromRaynot voidbut rather direct Item。这样,您甚至不需要在您的课程中为此设置一个字段,并且您不会忘记必须先调用它或设置哪个字段:

private Item SelectItemBeingInteractedWithFromRay()
{
    Ray ray = camera.ViewportPointToRay(Vector3.one / 8f);

    Debug.DrawRay(ray.origin,ray.direction * 8f, Color.red); 

    if (Physics.Raycast(ray, out var hitInfo, 8f, layerMask))
    {
        var hitItem = hitInfo.collider.GetComponent<Item>();

        // your Update already makes a null check so let it handle the outcome
        return hitItem;
    }

    return null;
}

然后像这样使用它

private void Update()
{
    var currentItem = SelectItemBeingInteractedWithFromRay();

    if(currentItem)
    {
        itemNameText.text = "Pickup" + currentItem.name;

        ...
    }
    ...
}

推荐阅读