Unity3d 简易计时器.

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

public delegate void CompleteEvent();
public delegate void UpdateEvent(float t);
public class HallTimer : MonoBehaviour
{
    UpdateEvent updateEvent;
    CompleteEvent completeEvent;

    /// <summary>
    /// 计时的总时间
    /// </summary>
    float timeTarget;
    /// <summary>
    /// 开始计时的时间
    /// </summary>
    float timeStart;
    /// <summary>
    /// 现在系统的时间
    /// </summary>
    float timeNow;
    /// <summary>
    /// 计时偏差
    /// </summary>
    float offsetTime;
    /// <summary>
    /// 是否已经开始计时
    /// </summary>
    bool isTimerStart;
    /// <summary>
    /// 是否在计时结束后自毁
    /// </summary>
    bool isKillSelf = true;
    /// <summary>
    /// 是否已经结束计时
    /// </summary>
    bool isEnd;
    /// <summary>
    /// 是否忽略时间速率
    /// </summary>
    bool isIgnoreTimeScale = true;
    /// <summary>
    /// 是否重复计时
    /// </summary>
    bool isRepeate;

    float _Time
    {
        get
        {
            return isIgnoreTimeScale ? Time.realtimeSinceStartup : Time.deltaTime;
        }
    }

    /// <summary>
    /// 现在的时间剩余
    /// </summary>
    float now;
    /// <summary>
    /// 暂停时的时间
    /// </summary>
    float _pauseTime;

    void Update()
    {
        if (isTimerStart)
        {
            timeNow = _Time - offsetTime;
            now = timeNow - timeStart;
            updateEvent?.Invoke(Mathf.Clamp01(now / timeTarget));
            if (now > timeTarget)
            {
                completeEvent?.Invoke();
                if (!isRepeate)
                {
                    destory();
                }
                else
                {
                    reStartTimer();
                }
            }
        }
    }

    public float GetLeftTime()
    {
        return Mathf.Clamp(timeTarget - now, 0, timeTarget);
    }

    /// <summary>
    /// 暂停计时
    /// </summary>
    public void pauseTimer()
    {
        if (isEnd)
        {
            if (Const.GAME_DEBUG == 1)
            {
                Debug.LogWarning("计时已经结束!");
            } 
        }
        else
        {
            if (isTimerStart)
            {
                isTimerStart = false;
                _pauseTime = _Time;
            }
        }
    }
    /// <summary>
    /// 继续计时
    /// </summary>
    public void connitueTimer()
    {
        if (isEnd)
        {
            if (Const.GAME_DEBUG == 1)
            {
                Debug.LogWarning("计时已经结束!请从新计时!");
            }
        }
        else
        {
            if (!isTimerStart)
            {
                offsetTime += (_Time - _pauseTime);
                isTimerStart = true;
            }
        }
    }

    private void OnApplicationPause(bool pause)
    {
        if (pause)
        {
            //pauseTimer();
        }
        else
        {
            //connitueTimer();       
        }
    }
    public void destory()
    {
        isTimerStart = false;
        isEnd = true;
        if (isKillSelf)
        {
            Destroy(gameObject);
        }
    }

    public void reStartTimer()
    {
        timeStart = _Time;
        offsetTime = 0;
    }

    /// <summary>开始计时</summary>
    /// <param name="time_">总时长</param>
    /// <param name="completeEvent_">计时结束回调</param>
    /// <param name="update">计时中回调</param>
    /// <param name="isDestory_">结束计时后是否自毁</param>
    /// <param name="isIgnoreTimeScale_">是否不受时间速率的影响</param>
    /// <param name="isRepeate_">是否重复计时</param>
    public void startTiming(float time_, CompleteEvent completeEvent_, UpdateEvent update = null, bool isIgnoreTimeScale_ = true, bool isRepeate_ = false, bool isDestory_ = true)
    {
        timeTarget = time_;
        if (completeEvent_ != null)
            completeEvent = completeEvent_;
        if (update != null)
            updateEvent = update;
        isKillSelf = isDestory_;
        isIgnoreTimeScale = isIgnoreTimeScale_;
        isRepeate = isRepeate_;

        timeStart = _Time;
        offsetTime = 0;
        isEnd = false;
        isTimerStart = true;
    }
    /// <summary>
    /// 创建计时器
    /// </summary>
    /// <param name="gobjName">
    /// 计时器名字
    /// </param>
    public static HallTimer createTimer(string gobjName = "HallTimer")
    {
        GameObject g = new GameObject(gobjName);
        HallTimer timer = g.AddComponent<HallTimer>();
        return timer;
    }
}

注释很清晰拉,引用自这里:
https://blog.csdn.net/fucun1984686003/article/details/46919775

Lua判断字符宽度值

function UtilCalcStrWidth(str,size, lan)
local fontSize = size
local
lenInByte = #str
local
width = 0

for i=1,lenInByte do
local
curByte = string.byte(str, i)
local byteCount = 1;
if curByte>0 and curByte<=127 then
byteCount = 1
elseif curByte>=192 and curByte<223 then
byteCount = 2
elseif curByte>=224 and curByte<239 then
byteCount = 3
elseif curByte>=240 and curByte<=247 then
byteCount = 4
end

local
char = string.sub(str, i, i+byteCount-1)
i = i + byteCount -1

if byteCount == 1 then
width = width + fontSize * 0.5
--print(char)
else
width = width + fontSize
--print(char)
end
end
--print("总宽度: "..width)
if lan == Language_index.SAUDIARABIA then
return
width / 1.5
else
return
width
end
end


在多语言中,各个国家的文字算出来的宽度不是很准确,目前原因还不明。。。

Lua时间获取

	local utimetable = os.date("*t", os.time()); 
	local year = utimetable.year
	local month = utimetable.month
	local data = utimetable.day
	-- 获取到本月第一天是周几
	local data = os.date("%w",os.time({year =year, month = month, day =1, hour =12, min =0, sec = 0}))
        -- 上面也可以用下面的这种方式来取年,月,日,这里为了区分方式,来标写一下。
	self.m_startDay = tonumber(data)
	-- 获取本月的总天数
	local totalDay = os.date("%d",os.time({year=os.date("%Y"),month=os.date("%m")+1,day=0}))
	self.m_totalDay = tonumber(totalDay)

不知道对不对。

做为一名用户,如果给作者提了一个建议或者需求,然后该用户在某一天发现自己之前提过的建议或者需求被以某种方式在该产品中实现或显现出来,那么该用户的内心一定有会有某种状态的。但游戏不一样,游戏其实在我心理不是产品,是艺术品,我理解的艺术品强调的就是自我表达,你见过谁给某个画家提需求,让他那样画,这样画不。。。感觉好神奇,这就是市场的力量吧,现在的游戏真是只是一种产品了,所有的东西好像也都是这样,需求决定一切,也就是说,钱决定一切。。。