UnityEngine.Time类属性解析

UnityEngine.Time类包含的属性:

public static int captureFramerate { get; set; }
public static float deltaTime { get; }
public static float fixedDeltaTime { get; set; }
public static float fixedTime { get; }
public static int frameCount { get; }
public static float maximumDeltaTime { get; set; }
public static float realtimeSinceStartup { get; }
public static int renderedFrameCount { get; }
public static float smoothDeltaTime { get; }
public static float time { get; }
public static float timeScale { get; set; }
public static float timeSinceLevelLoad { get; }
public static float unscaledDeltaTime { get; }
public static float unscaledTime { get; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

———————————分割线—————————————– 
1、 UnityEngine.Time.captureFramerate: 
一旦设置了这个值(非0),每一帧会以1.0f/captureFramerate的时间更新(相对于Time.time,每一帧执行的真实时间还是不变的,其实这里再乘以Time.timeScale更合适),说白了就是改变每一帧所用的时间。这个属性并不改变Time.timeScale和Application.targetFrameRate,先上图: 
我先不设置UnityEngine.Time.captureFramerate

void Start () 
{
    //Time.captureFramerate = 10;
}

void Update () 
{
    Debug.Log(string.Format("第{0}帧----Time.timeScale:{1}  Time.deltaTime:{2}  Time.time:{3}  系统时间:{4}"
        , Time.frameCount, Time.timeScale, Time.deltaTime, Time.time, System.DateTime.Now.ToString("HH:mm:ss.ffff")));
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

看输出结果: 
这里写图片描述 
结果和我们平时看到的一样

下面我们来设置一下UnityEngine.Time.captureFramerate = 10; 
再看输出结果: 
这里写图片描述 
相信大家都看出来其中的差别了,虽然Time.timeScale没有变,但是Time.time确实比系统时间加快了,如果设置了Time.timeScale, 也会影响结果的,这个属性在使用的时候要特别注意了。

2、UnityEngine.Time.deltaTime: 
时间增量,依据Time.time,在Update里调用返回的是完成上一帧的时间,在FixedUpdate里调用返回的是FixedTimeStep的值。

3、UnityEngine.Time.fixedDeltaTime : 
固定增量时间,返回FixedTimeStep。FixedUpdate执行的时间间隔和物理检测的时间间隔。 
注意一下,这个是依据的是Time.time,也就是当Time.time累加的值等于了FixedTimeStep,那么FixedUpdate和物理检测就会执行,可以理解成当时间被加速,和此时间有关的会被更频繁的执行,所以当Time.timeScale为0时,FixedUpdate不会被执行。

4、UnityEngine.Time.fixedTime : 
固定时间,上一次FixedUpdate开始执行的时间,从程序开始计时。

5、UnityEngine.Time.frameCount : 
帧计数器,返回游戏一共经过了多少帧。

6、UnityEngine.Time.maximumDeltaTime : 
一帧所需的最大时间,如果一帧所需的时间可能大于这个值,那么一些物理检测和其他一些固定帧的更新将会减少执行。

7、UnityEngine.Time.realtimeSinceStartup : 
从程序启动到现在的时间,依据系统时间,不受Time.timeScale影响,当程序处于后台时,这个时间依然有效,不会停止计时,不管程序可不可以在后台运行。

8、UnityEngine.Time.renderedFrameCount : 
这个没有找到任何官方文档,比较奇怪。从字面上理解,就是被渲染帧的次数。尝试在Update(还有FixedUpdate和LateUpdate,这两个和Update的值是一样的)里输出一下,会发现这个次数每次都是增加2,而不是增加1,这就很奇怪吧,Update是每一帧都要执行的,这个是肯定的,也就是再每一帧其实是渲染了两次的。想了一下,在一帧中,还有可能被执行的还有OnGUI,结果在里面输出一下发现,多增加的1果然是在这里面。这个应该用的比较少。

9、UnityEngine.Time.smoothDeltaTime : 
一个平滑淡出Time.deltaTime的时间。在Update里和Time.deltaTime输出比较一下就会发下,这个值是当前的Time.deltaTime和上一帧的Time.smoothDeltaTime的一个差值的中间值。

10、UnityEngine.Time.time : 
程序内部的一个时间,返回当前帧开始的时间,受Time.timaScale影响。在FixedUpdate里调用,将返回Time.fixedTime。当程序处于后台时,如果程序不可以在后台运行,这个时间将失效,不会再计时了。

11、UnityEngine.Time.timeScale : 
时间缩放,影响一切基于Time.time的行为。

12、UnityEngine.Time.timeSinceLevelLoad : 
从场景加载完到现在的时间,基于Time.time。

13、UnityEngine.Time.unscaledDeltaTime : 
忽略Time.timeScale的Time.deltaTime。在刚开始的两帧貌似不太准

14、UnityEngine.Time.unscaledTime : 
把每一帧的Time.unscaledDeltaTime 加起来就是这个属性的值,虽然说理解功能上Time.realtimeSinceStartup 有点相似,当时两者并不想等,就是因为Time.unscaledDeltaTime在程序开始不太准确的原因,导致和 realtimeSinceStartup 会有误差,这个要注意一下。

总结: 
两种时间一定要分清,一个是依赖于系统的时间,它的一秒等于现实世界的一秒;另一个是程序自己的时间,这个时间可人为控制(加速,减速),大部分属性都是基于这个时间的。

转载于:https://www.cnblogs.com/lancidie/p/8036986.html

using System.Collections; using TMPro; using UnityEngine; using UnityEngine.SceneManagement; public enum Battle { Start, PlayerTurn, EnemyTurn, Lose, Win } public class BattleSystem : MonoBehaviour { public enum gameover{win,lose} public Battle State; public float typingSpeed = 0.05f; private bool isTyping = false; public GameObject PlayerPrefeb; public GameObject EnemyPrefeb; public Transform PlayerPosition; public Transform EnemyPosition; private Playermessage playerpeople; private Enemymessage emenypeople; public EnemyBattleHUD enemyHUD; public PlayerBattleHUD playerHUD; public TextMeshProUGUI Text; public GameObject F; public GameObject m; public GameObject back; public GameObject select1; public GameObject select2; public Color flash; private Color Originalcolor; public float Time; public UnityEngine.UI.Image image; public Animator animator; private Camera mainCamera; private Vector3 originalCameraPosition; public UnityEngine.UI.Image attackphoto; public UnityEngine.UI.Image attackphoto2; void Start() { mainCamera = Camera.main; if (mainCamera != null) { originalCameraPosition = mainCamera.transform.localPosition; } State = Battle.Start; StartCoroutine(SetupBattle()); } private IEnumerator SetupBattle() { GameObject player = Instantiate(PlayerPrefeb, PlayerPosition); playerpeople = player.GetComponent<Playermessage>(); GameObject emeny = Instantiate(EnemyPrefeb, EnemyPosition); emenypeople = emeny.GetComponent<Enemymessage>(); playerHUD.SetHUD(playerpeople); enemyHUD.SetHUD(emenypeople); // 显示开场信息(带打字效果) yield return StartCoroutine(TypeText("Let me feel your power now, don't make me bored^_^", 0.5f)); yield return new WaitForSeconds(0.5f); if (F != null) F.SetActive(false); if (m != null) m.SetActive(true); yield return StartCoroutine(TypeText("I can't lose here", 0.5f)); yield return new WaitForSeconds(0.5f); if (m != null) m.SetActive(false); yield return StartCoroutine(TypeText("--Please consider your decision--", 2f)); State = Battle.PlayerTurn; PlayerTurn(); } // 玩家回合逻辑 private void PlayerTurn() { StartCoroutine(TypeText("Choose your action...", 0f)); } public void OnAttackButton() { if (State != Battle.PlayerTurn) return; StartCoroutine(PlayerAttack()); } private IEnumerator PlayerAttack() { yield return StartCoroutine(TypeText("Get out of my way!!!", 0f)); yield return new WaitForSeconds(1f); attackphoto.gameObject.SetActive(true); // 使用新的伤害计算方法 float damageDealt = player.CalculateDamage(); yield return StartCoroutine(TypeText($"Dealt {damageDealt} damage!", 0f)); yield return new WaitForSeconds(1f); attackphoto.gameObject.SetActive(false); // 调用新的TakeDamage方法 bool IsDead = emenypeople.TakeDamage(damageDealt); enemyHUD.SetHUD(emenypeople); if (IsDead) { State = Battle.Win; EndBattle(); } else { State = Battle.EnemyTurn; StartCoroutine(EnemyTurn()); } } private IEnumerator EnemyTurn() { yield return StartCoroutine(TypeText("Looking my eyes...", 0f)); yield return new WaitForSeconds(0.5f); attackphoto2.gameObject.SetActive(true); yield return new WaitForSeconds(0.5f);animator.SetTrigger("shake"); StartCoroutine(ShakeCamera(0.4f, 0.4f)); Originalcolor = image.color; StartCoroutine(flashboom()); attackphoto2.gameObject.SetActive(false); float damageDealt = GetComponent<SpeacialAttack>().GetDamage(); yield return StartCoroutine(TypeText($"Took {damageDealt} damage!", 0f)); bool IsDead = playerpeople.TakeDamage(); playerHUD.SetHUD(playerpeople); yield return new WaitForSeconds(1f); if (IsDead) { State = Battle.Lose; EndBattle(); } else { State = Battle.PlayerTurn; PlayerTurn(); } } private void EndBattle() { if (State == Battle.Win) { StartCoroutine(TypeText("Victory is mine!", 0f)); EndBattle(true); } else if (State == Battle.Lose) { StartCoroutine(TypeText("Defeat... I'll be back!", 0f)); EndBattle(false); } select1.SetActive(false); select2.SetActive(false); back.SetActive(true); } const string BATTLE_RESULT_KEY = "LastBattleResult"; public void EndBattle(bool isWin) { PlayerPrefs.SetInt(BATTLE_RESULT_KEY, isWin ? 1 : 0); PlayerPrefs.Save(); SceneManager.LoadScene("Traning"); } IEnumerator flashboom()//受击红屏效果 { image.color = flash; yield return new WaitForSeconds(Time); image.color = Originalcolor; } private IEnumerator ShakeCamera(float duration = 0.5f, float magnitude = 0.4f) { Vector3 originalPos = mainCamera.transform.localPosition; float elapsed = 0f; AnimationCurve attenuationCurve = AnimationCurve.EaseInOut(0, 1, 1, 0); while (elapsed < duration) { float attenuation = attenuationCurve.Evaluate(elapsed / duration); float x = Mathf.PerlinNoise(UnityEngine.Time.time * 30f, 0) * 2 - 1; float y = Mathf.PerlinNoise(0, UnityEngine.Time.time * 30f) * 2 - 1; // 5. 应用衰减后的震动幅度 Vector3 shakeOffset = new Vector3(x, y, 0) * magnitude * attenuation; mainCamera.transform.localPosition = originalPos + shakeOffset; // 6. 使用unscaledDeltaTime确保时间精确 elapsed += UnityEngine.Time.unscaledDeltaTime; yield return null; } // 7. 平滑回归原位 float returnDuration = 0.2f; float returnElapsed = 0f; Vector3 currentPos = mainCamera.transform.localPosition; while (returnElapsed < returnDuration) { mainCamera.transform.localPosition = Vector3.Lerp( currentPos, originalPos, returnElapsed / returnDuration ); returnElapsed += UnityEngine.Time.unscaledDeltaTime; yield return null; } mainCamera.transform.localPosition = originalPos; } public IEnumerator TypeText(string sentence, float initialDelay = 0f) { if (Text == null) yield break; isTyping = true; yield return new WaitForSeconds(initialDelay); Text.text = ""; foreach (char letter in sentence.ToCharArray()) { Text.text += letter; yield return new WaitForSeconds(typingSpeed); } isTyping = false; } }using UnityEngine; [System.Serializable] public class Playermessage : MonoBehaviour { // 角色基本属性 [Header("角色属性")] public string characterName; public int level = 100; public float attackPower=50; public float defense; public float maxHealth; [SerializeField] private float currentHealth; // 伤害计算参数 [Header("伤害计算")] public float criticalChance = 0.5f; public float criticalMultiplier = 1.5f; public float damageRandomness = 0.1f; // 属性访问器 public float CurrentHealth => currentHealth; // 初始化 private void Start() { currentHealth = maxHealth; } // 伤害计算核心方法 public float CalculateDamage() { // 基础伤害 = 攻击力 * (1 ± 随机波动) float baseDamage = attackPower * (1 + Random.Range(-damageRandomness, damageRandomness)); // 暴击判定 if (Random.value <= criticalChance) { baseDamage *= criticalMultiplier; Debug.Log($"暴击! 伤害: {baseDamage}"); } return Mathf.Max(1, baseDamage); // 确保最小伤害为1 } // 受到伤害处理 public bool TakeDamage(float incomingDamage) { // 实际伤害 = 输入伤害 - 防御力 (至少造成1点伤害) float actualDamage = Mathf.Max(1, incomingDamage - defense); // 更新生命值 currentHealth -= actualDamage; currentHealth = Mathf.Clamp(currentHealth, 0, maxHealth); Debug.Log($"{characterName}受到{actualDamage}点伤害, 剩余生命值: {currentHealth}/{maxHealth}"); // 返回是否死亡 return currentHealth <= 0; } } using UnityEngine; [System.Serializable] public class Enemymessage : MonoBehaviour { // 角色基本属性 [Header("角色属性")] public string characterName; public int level = 1; public float attackPower=50; public float defense; public float maxHealth; [SerializeField] private float currentHealth; // 伤害计算参数 [Header("伤害计算")] public float criticalChance = 0.5f; public float criticalMultiplier = 1.5f; public float damageRandomness = 0.1f; // 属性访问器 public float CurrentHealth => currentHealth; // 初始化 private void Start() { currentHealth = maxHealth; } // 伤害计算核心方法 public float CalculateDamage() { // 基础伤害 = 攻击力 * (1 ± 随机波动) float baseDamage = attackPower * (1 + Random.Range(-damageRandomness, damageRandomness)); // 暴击判定 if (Random.value <= criticalChance) { baseDamage *= criticalMultiplier; Debug.Log($"暴击! 伤害: {baseDamage}"); } return Mathf.Max(1, baseDamage); // 确保最小伤害为1 } // 受到伤害处理 public bool TakeDamage(float incomingDamage) { // 实际伤害 = 输入伤害 - 防御力 (至少造成1点伤害) float actualDamage = Mathf.Max(1, incomingDamage - defense); // 更新生命值 currentHealth -= actualDamage; currentHealth = Mathf.Clamp(currentHealth, 0, maxHealth); Debug.Log($"{characterName}受到{actualDamage}点伤害, 剩余生命值: {currentHealth}/{maxHealth}"); // 返回是否死亡 return currentHealth <= 0; } } using UnityEngine; [System.Serializable] public class Enemymessage : MonoBehaviour { // 角色基本属性 [Header("角色属性")] public string characterName; public int level = 1; public float attackPower=50; public float defense; public float maxHealth; [SerializeField] private float currentHealth; // 伤害计算参数 [Header("伤害计算")] public float criticalChance = 0.5f; public float criticalMultiplier = 1.5f; public float damageRandomness = 0.1f; // 属性访问器 public float CurrentHealth => currentHealth; // 初始化 private void Start() { currentHealth = maxHealth; } // 伤害计算核心方法 public float CalculateDamage() { // 基础伤害 = 攻击力 * (1 ± 随机波动) float baseDamage = attackPower * (1 + Random.Range(-damageRandomness, damageRandomness)); // 暴击判定 if (Random.value <= criticalChance) { baseDamage *= criticalMultiplier; Debug.Log($"暴击! 伤害: {baseDamage}"); } return Mathf.Max(1, baseDamage); // 确保最小伤害为1 } // 受到伤害处理 public bool TakeDamage(float incomingDamage) { // 实际伤害 = 输入伤害 - 防御力 (至少造成1点伤害) float actualDamage = Mathf.Max(1, incomingDamage - defense); // 更新生命值 currentHealth -= actualDamage; currentHealth = Mathf.Clamp(currentHealth, 0, maxHealth); Debug.Log($"{characterName}受到{actualDamage}点伤害, 剩余生命值: {currentHealth}/{maxHealth}"); // 返回是否死亡 return currentHealth <= 0; } }我现在更新了后面两个脚本,帮我修改BattleSystem,写出BattleSystem全代码
07-31
下面这个Xcharts示例脚本怎么使用 using System.Collections; using UnityEngine; using XCharts.Runtime; namespace XCharts.Example { [DisallowMultipleComponent] public class Example10_LineChart : MonoBehaviour { private LineChart chart; private Serie serie; private int m_DataNum = 8; private void OnEnable() { StartCoroutine(PieDemo()); } IEnumerator PieDemo() { while (true) { StartCoroutine(AddSimpleLine()); yield return new WaitForSeconds(2); StartCoroutine(ChangeLineType()); yield return new WaitForSeconds(8); StartCoroutine(LineAreaStyleSettings()); yield return new WaitForSeconds(5); StartCoroutine(LineArrowSettings()); yield return new WaitForSeconds(2); StartCoroutine(LineSymbolSettings()); yield return new WaitForSeconds(7); StartCoroutine(LineLabelSettings()); yield return new WaitForSeconds(3); StartCoroutine(LineMutilSerie()); yield return new WaitForSeconds(5); } } IEnumerator AddSimpleLine() { chart = gameObject.GetComponent<LineChart>(); if (chart == null){ chart = gameObject.AddComponent<LineChart>(); chart.Init(); } chart.GetChartComponent<Title>().text = "LineChart - 折线图"; chart.GetChartComponent<Title>().subText = "普通折线图"; var yAxis = chart.GetChartComponent<YAxis>(); yAxis.minMaxType = Axis.AxisMinMaxType.Custom; yAxis.min = 0; yAxis.max = 100; chart.RemoveData(); serie = chart.AddSerie<Line>("Line"); for (int i = 0; i < m_DataNum; i++) { chart.AddXAxisData("x" + (i + 1)); chart.AddData(0, UnityEngine.Random.Range(30, 90)); } yield return new WaitForSeconds(1); } IEnumerator ChangeLineType() { chart.GetChartComponent<Title>().subText = "LineTyle - 曲线图"; serie.lineType = LineType.Smooth; chart.RefreshChart(); yield return new WaitForSeconds(1); chart.GetChartComponent<Title>().subText = "LineTyle - 阶梯线图"; serie.lineType = LineType.StepStart; chart.RefreshChart(); yield return new WaitForSeconds(1); serie.lineType = LineType.StepMiddle; chart.RefreshChart(); yield return new WaitForSeconds(1); serie.lineType = LineType.StepEnd; chart.RefreshChart(); yield return new WaitForSeconds(1); chart.GetChartComponent<Title>().subText = "LineTyle - 虚线"; serie.lineStyle.type = LineStyle.Type.Dashed; chart.RefreshChart(); yield return new WaitForSeconds(1); chart.GetChartComponent<Title>().subText = "LineTyle - 点线"; serie.lineStyle.type = LineStyle.Type.Dotted; chart.RefreshChart(); yield return new WaitForSeconds(1); chart.GetChartComponent<Title>().subText = "LineTyle - 点划线"; serie.lineStyle.type = LineStyle.Type.DashDot; chart.RefreshChart(); yield return new WaitForSeconds(1); chart.GetChartComponent<Title>().subText = "LineTyle - 双点划线"; serie.lineStyle.type = LineStyle.Type.DashDotDot; chart.RefreshChart(); serie.lineType = LineType.Normal; chart.RefreshChart(); } IEnumerator LineAreaStyleSettings() { chart.GetChartComponent<Title>().subText = "AreaStyle 面积图"; serie.EnsureComponent<AreaStyle>(); serie.areaStyle.show = true; chart.RefreshChart(); yield return new WaitForSeconds(1f); chart.GetChartComponent<Title>().subText = "AreaStyle 面积图"; serie.lineType = LineType.Smooth; serie.areaStyle.show = true; chart.RefreshChart(); yield return new WaitForSeconds(1f); chart.GetChartComponent<Title>().subText = "AreaStyle 面积图 - 调整透明度"; while (serie.areaStyle.opacity > 0.4) { serie.areaStyle.opacity -= 0.6f * Time.deltaTime; chart.RefreshChart(); yield return null; } yield return new WaitForSeconds(1); chart.GetChartComponent<Title>().subText = "AreaStyle 面积图 - 渐变"; serie.areaStyle.toColor = Color.white; chart.RefreshChart(); yield return new WaitForSeconds(1); } IEnumerator LineArrowSettings() { chart.GetChartComponent<Title>().subText = "LineArrow 头部箭头"; chart.GetSerie(0).EnsureComponent<LineArrow>(); serie.lineArrow.show = true; serie.lineArrow.position = LineArrow.Position.Start; chart.RefreshChart(); yield return new WaitForSeconds(1); chart.GetChartComponent<Title>().subText = "LineArrow 尾部箭头"; serie.lineArrow.position = LineArrow.Position.End; chart.RefreshChart(); yield return new WaitForSeconds(1); serie.lineArrow.show = false; } /// <summary> /// SerieSymbol 相关设置 /// </summary> /// <returns></returns> IEnumerator LineSymbolSettings() { chart.GetChartComponent<Title>().subText = "SerieSymbol 图形标记"; while (serie.symbol.size < 5) { serie.symbol.size += 2.5f * Time.deltaTime; chart.RefreshChart(); yield return null; } chart.GetChartComponent<Title>().subText = "SerieSymbol 图形标记 - 空心圆"; yield return new WaitForSeconds(1); chart.GetChartComponent<Title>().subText = "SerieSymbol 图形标记 - 实心圆"; serie.symbol.type = SymbolType.Circle; chart.RefreshChart(); yield return new WaitForSeconds(1); chart.GetChartComponent<Title>().subText = "SerieSymbol 图形标记 - 三角形"; serie.symbol.type = SymbolType.Triangle; chart.RefreshChart(); yield return new WaitForSeconds(1); chart.GetChartComponent<Title>().subText = "SerieSymbol 图形标记 - 正方形"; serie.symbol.type = SymbolType.Rect; chart.RefreshChart(); yield return new WaitForSeconds(1); chart.GetChartComponent<Title>().subText = "SerieSymbol 图形标记 - 菱形"; serie.symbol.type = SymbolType.Diamond; chart.RefreshChart(); yield return new WaitForSeconds(1); chart.GetChartComponent<Title>().subText = "SerieSymbol 图形标记"; serie.symbol.type = SymbolType.EmptyCircle; chart.RefreshChart(); yield return new WaitForSeconds(1); } /// <summary> /// SerieLabel相关配置 /// </summary> /// <returns></returns> IEnumerator LineLabelSettings() { chart.GetChartComponent<Title>().subText = "SerieLabel 文本标签"; serie.EnsureComponent<LabelStyle>(); chart.RefreshChart(); while (serie.label.offset[1] < 20) { serie.label.offset = new Vector3(serie.label.offset.x, serie.label.offset.y + 20f * Time.deltaTime); chart.RefreshChart(); yield return null; } yield return new WaitForSeconds(1); chart.RefreshChart(); yield return new WaitForSeconds(1); serie.label.textStyle.color = Color.white; serie.label.background.color = Color.grey; serie.labelDirty = true; chart.RefreshChart(); yield return new WaitForSeconds(1); serie.label.show = false; chart.RefreshChart(); } /// <summary> /// 添加多条线图 /// </summary> /// <returns></returns> IEnumerator LineMutilSerie() { chart.GetChartComponent<Title>().subText = "多系列"; var serie2 = chart.AddSerie<Line>("Line2"); serie2.lineType = LineType.Normal; for (int i = 0; i < m_DataNum; i++) { chart.AddData(1, UnityEngine.Random.Range(30, 90)); } yield return new WaitForSeconds(1); var serie3 = chart.AddSerie<Line>("Line3"); serie3.lineType = LineType.Normal; for (int i = 0; i < m_DataNum; i++) { chart.AddData(2, UnityEngine.Random.Range(30, 90)); } yield return new WaitForSeconds(1); var yAxis = chart.GetChartComponent<YAxis>(); yAxis.minMaxType = Axis.AxisMinMaxType.Default; chart.GetChartComponent<Title>().subText = "多系列 - 堆叠"; serie.stack = "samename"; serie2.stack = "samename"; serie3.stack = "samename"; chart.RefreshChart(); yield return new WaitForSeconds(1); } } }
最新发布
08-16
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值