1.拆解原始机制
1.主要分为四个部分:填充区,填充条,判定框,进度条。
2.第一个是判断填充条是否在判定框内,如果在就增加进度条进度,反之减少;第二个是控制填充条,如果按空格就增加宽度,反之减少;第三个是使得判定框可以随机移动。
2.制作环形进度条
创建Slider,并且更改设置(Transition改为None,取消Interactable),子物体Fill的Image Type改为Filled并且四周拉伸,底部图片Image Type改为Simple,把Handle Slide Area整个子物体删除,最后用一个图片遮盖中心点(因为本身进度条是扇形,遮住中间就会变为环形)。


3.小游戏逻辑
1.判断填充条与判定框关系
public class ProgressBarJudge : MonoBehaviour
{
public Slider slider;
public RectTransform progressBar;//填充条
public RectTransform decisionBox;//判定框
private float barWidth;//填充条的宽度
private float boxPosX;//判定框的x
public float progressValue;//进度值
private bool isComplete;//是否进度为百分之百
private void Update()
{
barWidth = progressBar.sizeDelta.x;
boxPosX = decisionBox.anchoredPosition.x;
if (barWidth >= boxPosX * 10f + 1000f && barWidth <= boxPosX * 10f + 2000f)
{
progressValue += 0.01f;
}
else
{
if (progressValue >= 0)
progressValue -= 0.005f;
else
progressValue = 0;
}
if(isComplete)
return;
slider.value = progressValue / 10f;
if (slider.value >= 1)
{
isComplete = true;
slider.value = 1;
//TODO:执行任务
}
}
}
注: 填充条宽度与判定框x轴位置的映射关系
2.控制填充条
public class BarMoveController : MonoBehaviour
{
public RectTransform progressBar; // 需要调整宽度的UI图片
public float growthSpeed; // 按下空格时宽度增长速度
public float shrinkSpeed; // 如果不按空格时宽度减少的速度
public float widthMax = 6150;
private float targetWidth; // 目标宽度
private bool isSpacePressed; // 是否按下空格
void Start()
{
// 初始化宽度
targetWidth = progressBar.sizeDelta.x;
}
void Update()
{
// 检测空格键是否被按下
isSpacePressed = Input.GetKey(KeyCode.Space);
if (isSpacePressed)
{
// 空格键按下时,宽度增加
targetWidth += growthSpeed * 1.5f;
}
else
{
// 空格键未按下时,宽度减少,最小为0
targetWidth -= shrinkSpeed * 1.5f;
}
// 保证宽度不会小于0
targetWidth = Mathf.Max(targetWidth, 0f);
// 更新图片宽度
if(targetWidth <= widthMax)
progressBar.sizeDelta = new Vector2(targetWidth, progressBar.sizeDelta.y);
else
progressBar.sizeDelta = new Vector2(widthMax, progressBar.sizeDelta.y);
}
}
3.判定框的随机移动
public class SmoothRandomMoveUI : MonoBehaviour
{
public RectTransform decisionBox; // UI 图片的 RectTransform
public float moveSpeed = 5f; // 控制移动的速度
public float minDistance = 0f; // 随机目标的最小水平距离
public float maxDistance = 770f; // 随机目标的最大水平距离
private Vector2 targetPosition;
private float startTime;
void Start()
{
// 初始化目标位置
SetRandomTargetPosition();
}
void Update()
{
// 获取当前位置到目标位置的水平距离
float journeyLength = Mathf.Abs(decisionBox.anchoredPosition.x - targetPosition.x);//总距离
float distanceCovered = (Time.time - startTime) * moveSpeed;//当前移动距离
float fractionOfJourney = distanceCovered / journeyLength;
// 平滑过渡
decisionBox.anchoredPosition = Vector2.Lerp(decisionBox.anchoredPosition, targetPosition, fractionOfJourney);
// 如果到达目标位置,设置新的随机目标
if (fractionOfJourney >= 1.0f)
{
StartCoroutine(WaitSprite());
}
}
// 设置一个新的随机目标位置
void SetRandomTargetPosition()
{
float currentDistance;
float randomX;
do
{
randomX = Random.Range(minDistance, maxDistance);
currentDistance = Mathf.Abs(decisionBox.anchoredPosition.x - randomX);
} while (currentDistance > 500);
targetPosition = new Vector2(randomX, decisionBox.anchoredPosition.y);
startTime = Time.time;
}
IEnumerator WaitSprite()
{
yield return new WaitForSeconds(1f);
SetRandomTargetPosition();
}
}
22万+

被折叠的 条评论
为什么被折叠?



