unity3d - 为什么当我按住轻按时这不会改变填充量?
问题描述
我正在尝试设置按住拾取动画。按下左键时,此代码应更改精灵的填充量,但事实并非如此。基本上,当玩家看到一个可交互的对象时,会弹出一个窗口,告诉他们按住字母 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;
}
}
}
它应该改变填充量
解决方案
Input.GetMouseButtonDown
仅true
在一个帧中-按钮按下的帧。
true
在用户按下给定鼠标按钮的帧期间返回。
在那false
之后的框架中!
您可能更愿意使用的是Input.GetMouseButton
返回给定的鼠标按钮是否被按住。
if(Input.GetMouseButton(0))
只要true
按钮保持按下状态!
但是,我不太了解您对TimeTest
这里的其他变量和方法的使用。可能只是0
?你pickProgressImage.fillAmount
在两个不同的地方增加,而且TimeTest
..这让我有点困惑。而且你的一些方法是相当多余的。
您不需要进一步的变量来检查所需的时间是否已经过去......只需使用比较值来检查pickProgressImage.fillAmount
自身。Mathf.Approximately
float
同样对于增量,您不应该使用固定值0.1f
(这就是您声明浮点值的方式),而是使用Time.deltaTime
以将其他与帧速率相关的增量转换为与帧速率无关的“每秒增量”值。
您也不需要检查 if itemBeingPickedUp
is set or的方法null
:由于您的Item
is 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;
}
}
作为口味问题,我实际上也会将返回类型设置为SelectItemBeingInteractedWithFromRay
not void
but 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;
...
}
...
}
推荐阅读
- database - 如果数据库服务器更新到新版本,重写程序代码?
- html - 如何将 CSS 代码添加到网站构建器中的预构建主题
- c# - 在 ASP.Net Core 中使用 AJAX 将复选框列表类的值发送到服务器
- php - 在while循环内进行排序
- linux - Linux:如何删除大量文件?
- ruby - 如何修复 Ruby Rack SessionId 错误错误:解码 rack.session cookie 时未定义的类/模块 Rack::Session::SessionId
- sql - 如何在 Microsoft sql 查询中“跨组”?
- r - R中的交互项没有系数估计
- java - IntelliJ 配色方案定制
- c - 如何分析 /proc/pid/smaps