VR開發(fā)--虛擬與現(xiàn)實游戲(VR-狩獵)

國慶期間本來是想找份工作的冠句,結(jié)果目前沒有合適的轻掩。只好閉門造車。懦底。唇牧。感慨世事萬千,生命的神奇。廢話不多說丐重,三句就夠了腔召!

00.png
1、前期準備

1弥臼、PC平臺
2宴咧、資源(UI素材,粒子特效径缅,動畫等)
3掺栅、導入SteamVR
4、那個運行HTC Vive設(shè)備最少970顯卡

01.png

注意:全部選擇

2纳猪、導入3D視角
2.png
3氧卧、導入模型資源

需要那個手柄控制,就放置在那個手柄下

04.png
4氏堤、基于設(shè)備調(diào)整好模型與手柄之間的角度沙绝、距離
10.png
5、針對箭頭鼠锈,掛載腳本

設(shè)置箭頭的位置和控制箭頭的父物體闪檬,腳本在父物體掛載

05.png
6、設(shè)置弓與箭的觸發(fā)器
06.png
07.png
7购笆、實例化一個箭頭
08.png

箭頭與弓是分離的粗悯,所以在手柄控制器中,放置在string里面來達到收納箭頭同欠,控制箭頭的位置信息

10.png
12.png
8样傍、拉動弓箭

8.1箭頭控制器應(yīng)該拿到弓玄的起始位置

13.png

8.2弓箭的起始位置與拉動位置

14.png
15.png
9、箭的發(fā)射

箭頭所在的腳本:

16.png

箭頭控制器里面的方法:

17.png
18.png

射箭:

19.png

上面就是開發(fā)一款虛擬與現(xiàn)實最簡單的應(yīng)用(國外的開發(fā)牛人提供的素材)
箭頭控制器源碼:

using UnityEngine;
using System.Collections;
using System;

public class ArrowsManager : MonoBehaviour {
    public float dir; 
    // 實例化對象
    public static ArrowsManager instance;
    void Awake()
    {
        instance = this;
    }

    // 過渡游戲?qū)ο?    private GameObject curArrow;
    // 實際的箭頭
    public GameObject arrowPf;
    // 獲得VR設(shè)備(因為箭頭要在控制手柄上铺遂,所以必須要有手柄對象)
    public SteamVR_TrackedObject trackObj;

    // 擁有箭頭位置的對象衫哥,也就是箭頭在手柄內(nèi)部位置
    public GameObject stringAttachPoint;
    // 開始點
    public GameObject arrowStartPoint;
    // 弓玄的起始位置
    public GameObject StringStartPoint;
    // 判斷是否觸發(fā)
    private bool isAttached;

    void Update () {
        AttachArrow(); 
        PullString(); // 判斷拉弓
    }

    // 射箭  
    private void Fire()
    {
        curArrow.transform.parent = null;
        // 拿到當前箭頭的剛體組件
        var r = curArrow.GetComponent<Rigidbody>();
        r.useGravity = true; // 使用重力
        r.velocity = curArrow.transform.forward * 50f * dir; //設(shè)置剛體的速度

        // 將弓玄string還原
        stringAttachPoint.transform.position = StringStartPoint.transform.position;

        curArrow = null; // 射出去了,當前箭頭就為空
        isAttached = false; // 射出去后襟锐,就不會在觸發(fā)了撤逢。
    }

    // 箭頭的實時位置
    void AttachArrow()
    {
        if (curArrow == null)
        {  // 實例化箭頭
            curArrow = Instantiate(arrowPf);
            // 設(shè)置箭頭的父控件
            arrowPf.transform.parent = trackObj.transform;
            // 設(shè)置箭頭的地方坐標
            curArrow.transform.localPosition = new Vector3(0, 0, 0.256f);
            // 設(shè)置角度
            // Quaternion.identity就是指Quaternion(0,0,0,0),就是每旋轉(zhuǎn)前的初始角度,是一個確切的值,
            // 而transform.rotation是指本物體的角度,是一個屬性變量
            curArrow.transform.localRotation = Quaternion.identity;
        }
    }
    
    /*
     *觸發(fā)器觸發(fā)后調(diào)整箭頭位置
    */
    public void AttachBowToArrow()
    {
        // 當前箭頭的父控件 = 手柄的位置
        curArrow.transform.parent = stringAttachPoint.transform;
        // 當前箭頭的本地坐標就是開始箭頭的本地坐標(開始箭頭的坐標通過賦值對象的坐標來獲取)
        curArrow.transform.localPosition = arrowStartPoint.transform.localPosition;
        // 當前箭頭的旋轉(zhuǎn) = 開始箭頭的旋轉(zhuǎn)
        curArrow.transform.rotation = arrowStartPoint.transform.rotation;
        isAttached = true; // 標志位粮坞,觸發(fā)了蚊荣,其實也就調(diào)用了拉動弓玄方法
    }

    /*
     *拉動弓玄
    */
    public void PullString()
    {
        if (isAttached) // 如果觸發(fā),再調(diào)整箭頭的位置
        {
                // InverseTransformPoint:變換位置從自身坐標到世界坐標(弓玄的本地坐標轉(zhuǎn)換成世界坐標的X(就是拉動玄的長度))
                // 獲得轉(zhuǎn)換后的vector的X值
               dir = StringStartPoint.transform.InverseTransformPoint(trackObj.transform.position).x;
               print(StringStartPoint.transform.InverseTransformPoint(trackObj.transform.position));
            // 拿到初始弓玄與手柄設(shè)備的差值 
            // float dis = (StringStartPoint.transform.position - trackObj.transform.position).magnitude;
            // 箭頭的實際位置 = 起始位置+上面的差值
            if (dir < 0)
            {
                dir = 0;
            }
            dir = dir > 0.4f ? 0.4f : dir;
            stringAttachPoint.transform.localPosition = StringStartPoint.transform.localPosition + new Vector3(dir, 0, 0);

                // 獲得輸入的VR手柄設(shè)備
                var device = SteamVR_Controller.Input((int)ArrowsManager.instance.trackObj.index);

                // 如果扣動扳機(如果處于攻擊),發(fā)射弓箭
                if (device.GetTouch(SteamVR_Controller.ButtonMask.Trigger))
                {
                    Fire(); // 開火
                }
        }
    }
}

箭頭掛載的腳本:

using UnityEngine;
using System.Collections;
using System;

public class Arrows : MonoBehaviour {
    private bool isFire;
    private bool isAttached;

    void Update () {
        if (isFire)
        {   //當前的朝向  當前的位置+當前剛體的速率
            // LookAt: 朝向捞蚂,是一個相對坐標
            transform.LookAt(transform.position + transform.GetComponent<Rigidbody>().velocity);
        }
    }
    // 觸發(fā)器(API)
    void OnTriggerEnter(Collider c)
    {
        AttackArrow();
        AttackEnemy(c);
    }
    // 根據(jù)傳入的碰撞器標簽妇押,來攻擊怪物
    private void AttackEnemy(Collider c)
    {
        if (c.tag == "Enemy")
        {   // 拿到碰撞器所在物體的《怪物》腳本執(zhí)行TakeDamage方法
            c.gameObject.GetComponent<Enmy>().TakeDamage();
        }
    }

    public void Fire()
    {
        isFire = true;
    }
     // 攻擊
    public void AttackArrow()
    {
       // 獲得輸入的VR手柄設(shè)備
       var device = SteamVR_Controller.Input((int)ArrowsManager.instance.trackObj.index);

        // 如果扣動扳機(如果處于攻擊)
        if (isAttached == false && device.GetTouch(SteamVR_Controller.ButtonMask.Trigger)) 
        {
            // 拿到Arrowsmanager,調(diào)用箭頭的位置
             ArrowsManager.instance.AttachBowToArrow();
             isAttached = true;
        }   
    }
}

怪物生成腳本:

using UnityEngine;
using System.Collections;

public class EnemySpawner : MonoBehaviour {

    // 起始路點
    public PathNode m_startNode;

    // 保存所有的從XML讀取的數(shù)據(jù)
    ArrayList m_enemyList;

    // 存儲敵人出場順序
    public TextAsset xmldata;

    // 出場敵人的序列號
    int m_index = 0;

    // 距離下一個敵人的出場時間
    float m_timer = 0;

    int liveEnemy;

    
    void Start () {
        ReadXML();

        // 獲取初始敵人
        SpawnData date = (SpawnData)m_enemyList[m_index];
        m_timer = date.wait;
    }
    
    
    void Update () {
        SpawnEnemy();
    }

    // 每個一定時間生成一個敵人
    void SpawnEnemy()
    {
        if (m_index >= m_enemyList.Count)
        {
            return;
        }
        // 更新時間姓迅,等待下一個敵人
        m_timer -= Time.deltaTime;
        if (m_timer > 0)
        {
            return;
        }
        // 獲取下一個敵人的數(shù)據(jù)
        SpawnData data = (SpawnData)m_enemyList[m_index];
        // 如果下一個敵人是下一波敲霍,需要等待前一波敵人全部銷毀
        if (GameManager.Instance.wave < data.wave)
        {
            if (liveEnemy > 0)
            {
                return;
            }
            else
            {
                GameManager.Instance.wave = data.wave; // 更新wave數(shù)值
            }
        }
        m_index++;
        if (m_index < m_enemyList.Count)
        {
            m_timer = ((SpawnData)m_enemyList[m_index]).wait;// 更新等待的時間
        }
        // 讀取敵人的模型
        GameObject enemymodel = Resources.Load<GameObject>(data.enemyname);
       // Debug.Log("  調(diào)試    "+m_startNode.transform.position);
        // 實例化敵人的模型俊马,并轉(zhuǎn)向第一個路點
        Vector3 dir = m_startNode.transform.position - this.transform.position;
        // 預設(shè)物,位置,旋轉(zhuǎn)角度
        GameObject enmeyObj = (GameObject)Instantiate(enemymodel,this.transform.position, Quaternion.LookRotation(dir));

        // 添加Enemy
        Enmy eney = enmeyObj.AddComponent<Enmy>();
       
          // 設(shè)置敵人出發(fā)點
        eney.curNode = m_startNode;
        Debug.Log(m_startNode.transform.position+" 設(shè)置敵人出發(fā)點 ");
        // 根據(jù)data.level設(shè)置敵人數(shù)值肩杈,本示例只是簡單的根據(jù)波數(shù)增加敵人的生命
        eney.m_life = data.level * 3;
        eney.m_maxlife = data.level * 3;

        // 更新存活敵人數(shù)量
        liveEnemy++;
        // 為敵人指定死亡動作柴我,當敵人死亡回調(diào)減少敵人數(shù)量
        OnEnmyDeath(eney, (Enmy e) =>
         {
             liveEnemy--;
         });

    }
    // 定義了動作的函數(shù)
    void OnEnmyDeath(Enmy eney, System.Action<Enmy> onDeath)
    {
        eney.onDeath = onDeath;
    }

    void OnDrawGizmos()
    {
        Gizmos.DrawIcon(transform.position, "spawner.tif");
    }
    void ReadXML()
    {
        m_enemyList = new ArrayList();
        XMLParser xmlparse = new XMLParser();
        XMLNode node = xmlparse.Parse(xmldata.text);
        // 取得XML數(shù)據(jù)  = 傳入XML文件路徑
        XMLNodeList list = node.GetNodeList("ROOT>0>table");
        for (int i = 0; i < list.Count; i++)
        {
            string wave = node.GetValue("ROOT>0>table>" + i + ">@wave");
            string enemyname = node.GetValue("ROOT>0>table>" + i + ">@enemyname");
            string level = node.GetValue("ROOT>0>table>" + i + ">@level");
            string wait = node.GetValue("ROOT>0>table>" + i + ">@wait");

            SpawnData data = new SpawnData();
            data.wave = int.Parse(wave);
            data.enemyname = enemyname;
            data.level = int.Parse(level);
            data.wait = float.Parse(wait);

            m_enemyList.Add(data);
        }  
    }
    // xml數(shù)據(jù)
    public class SpawnData
    {   // 波數(shù)
        public int wave = 1;
        public string enemyname = "";
        public int level = 1;
        public float wait = 1.0f; 
    }
}
using UnityEngine;
using System.Collections;
using System;

public class Enmy : MonoBehaviour {

    public PathNode curNode; // 怪物的起始點
    public float speed = 2;  // 怪物的速度

    internal int m_life;
    internal int m_maxlife;

    public System.Action<Enmy> onDeath;
    void Start () {
        ShowEffect();
    }
    
    void Update () {
        RorateTo();
        MoveTo();
    }

    public void MoveTo()
    {
        Vector3 pos1 = this.transform.position; // 當前怪物所在位置
        Vector3 pos2 = Vector3.zero;
        if (curNode!=null)
        {
             pos2 = curNode.transform.position; // 起始點的位置
        }
        
        // 兩者之間的距離差值
        float dis = Vector2.Distance(new Vector2(pos1.x, pos1.z), new Vector2(pos2.x, pos2.z));
        
        // 判斷目的地
        if (dis < 0.3f)  // 到達目的地
        {
            if (curNode.next == null)
            {
                DestroyMe();
            }
            else {
                curNode = curNode.next; // 如果還有下個點,那么當前點就是起始點
            }
        }
        transform.Translate(new Vector3(0, 0, speed * Time.deltaTime)); // 移動
    }

    // internal : 只能在程序集中訪問的意思
    internal void TakeDamage()
    {   // 加載粒子資源
        var p = Resources.Load("CFX2_SoulsEscape Rainbow");
        // 實例化(預制物扩然,預制物位置艘儒,預制物角度)
        Instantiate(p, transform.position, Quaternion.identity);

        DestroyMe(); // 摧毀自己
    }

    // 例子特效
    void ShowEffect()
    {
        var p = Resources.Load("CFX2_EnemyDeathSkull");
        Instantiate(p, transform.position, Quaternion.identity);
    }

    // 旋轉(zhuǎn)視角
    public void RorateTo()
    {   // 拿到當前對象的歐拉值的Y軸角度
        //http://wiki.ceeger.com/script:unityengine:classes:transform:transform.eulerangles
        float cur = this.transform.eulerAngles.y;
        // 朝向當前點的方向
        transform.LookAt(curNode.transform);
        // 移向目標(從當前的歐拉Y值,相對于父級的y軸變換旋轉(zhuǎn)角度夫偶,目標速度*時間)
        float next = Mathf.MoveTowardsAngle(cur, this.transform.localEulerAngles.y, 120 * Time.deltaTime);
        //// 為當前對象賦值歐拉角
        this.transform.eulerAngles = new Vector3(0, next, 0);
    }

    private void DestroyMe()
    {
        onDeath(this);
        Destroy(gameObject);
    } 
}

怪物路徑控制器腳本

using UnityEngine;
using System.Collections;

public class PathManager : MonoBehaviour {

    public ArrayList PathNode;

    void Start () {
    
    }
    
    void Update () {
    
    }

    [ContextMenu("BuildPath")]
    void BuildPath()       // 編譯路徑
    {
        PathNode = new ArrayList(); // 初始化數(shù)組
        GameObject[] objs = GameObject.FindGameObjectsWithTag("pathnode"); // 找到所有Pathnode節(jié)點
        for (int i = 0; i < objs.Length; i++)
        {
            PathNode node = objs[i].GetComponent<PathNode>();  // 取出每一個節(jié)點
            PathNode.Add(node); 
        }
    }

    public void OnDrawGizmos()  // 窗口可見時界睁,每一幀調(diào)用這個函數(shù)
    {
        if (PathNode == null) return;
        Gizmos.color = Color.blue;
        foreach (PathNode item in PathNode)
        {
            if (item.next != null) // 只要有下一個點
            {
                Gizmos.DrawLine(item.transform.position, item.next.transform.position); //畫線
            }
        }
    }
}

怪物路徑

using UnityEngine;
using System.Collections;

public class PathNode : MonoBehaviour
{

    public PathNode parent;// PathNode類型的起始點
    public PathNode next;  // 下一個點
    void Start()
    {

    }

    void Update()
    {

    }
    public void SetNext(PathNode node)  // 設(shè)置下一個點
    {
        if (next != null)               // 如果下個點不存在
        {
            next.parent = null;        // 那么起始點也不存在
        }
        next = node;        //如果下個點存在,那么下個點就是傳入的這個點
        node.parent = this;   // 起始點就是當前點
    }

    // 在窗口可見時兵拢,每一幀都會調(diào)用這個函數(shù)翻斟。在其中進行Gizmos的繪制,也就是輔助編輯的線框體
    void OnDrawGizmos()  // 畫圖 當繪制Gizmos
    {
        Gizmos.DrawIcon(this.transform.position, "Node.tif");
    }
}

關(guān)于怪物路徑的編輯器的拓展工具條腳本(不用掛載说铃,只需要放置在Editor文件下访惜,沒有就創(chuàng)建)

using UnityEngine;
using UnityEditor;
using System.Collections;

public class PathTool : ScriptableObject
{
    static PathNode parent; // 靜態(tài)起始點

    [MenuItem("PathTool/Creat PathNode")]
    static void GreatePathNoce()
    {
        // 創(chuàng)建一個新的路點
        GameObject go = new GameObject();
        go.AddComponent<PathNode>(); // 添加PathNode腳本
        go.name = "pathnode";
        // 設(shè)置標簽
        go.tag = "pathnode";
        // 使該路點處于選擇狀態(tài) (這個將絕不返回預設(shè)物或者不可修改的物體)
        Selection.activeTransform = go.transform;
    }



    [MenuItem("PathTool/Set Parent %q")]
    static void SetParent()  // 設(shè)置起始點
    {
        //  Selection.activeGameObject 返回激活的游戲物體。(在檢查面板中顯示)
        //  SelectionMode.Unfiltered 返回整個選擇,
        //  Selection.GetTransforms(SelectionMode.Unfiltered).Length 
        //  允許對選擇類型進行精細的控制腻扇,使用SelectionMode枚舉類型债热。
        if (!Selection.activeGameObject || Selection.GetTransforms(SelectionMode.Unfiltered).Length > 1)
        {
            return;
        }
        // 如果選擇的游戲?qū)ο蟮臉撕?= 點標簽
        if (Selection.activeGameObject.tag.CompareTo("pathnode") == 0)
        {   // 那么起始點 = 選中游戲?qū)ο蟮乃谀_本
            parent = Selection.activeGameObject.GetComponent<PathNode>();
            Debug.Log("設(shè)置" + parent.name + "起始點.");
        }
    }

    [MenuItem("PathTool/Set Next")]
    static void SetNextChild()
    {
        // 沒有選擇激活得游戲物體,并且沒有起始點幼苛,并且所有選擇的長度>1
        if (!Selection.activeGameObject || parent == null || Selection.GetTransforms(SelectionMode.Unfiltered).Length > 1)
        {
            return;
        }
        // 如果選擇的激活的游戲?qū)ο蟮臉撕?== pathNode
        if (Selection.activeGameObject.tag.CompareTo("pathnode") == 0)
        {
            parent.SetNext(Selection.activeGameObject.GetComponent<PathNode>()); // 那么設(shè)置下一個點
            parent = null;

            Debug.Log("設(shè)置" + Selection.activeGameObject.name + "所選擇激活的游戲?qū)ο蟮拿?);
        }
        
    }
}

20.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末窒篱,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子蚓峦,更是在濱河造成了極大的恐慌舌剂,老刑警劉巖济锄,帶你破解...
    沈念sama閱讀 221,576評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件暑椰,死亡現(xiàn)場離奇詭異,居然都是意外死亡荐绝,警方通過查閱死者的電腦和手機一汽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來低滩,“玉大人召夹,你說我怎么就攤上這事∷∧” “怎么了监憎?”我有些...
    開封第一講書人閱讀 168,017評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長婶溯。 經(jīng)常有香客問我鲸阔,道長偷霉,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,626評論 1 296
  • 正文 為了忘掉前任褐筛,我火速辦了婚禮类少,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘渔扎。我一直安慰自己硫狞,他們只是感情好,可當我...
    茶點故事閱讀 68,625評論 6 397
  • 文/花漫 我一把揭開白布晃痴。 她就那樣靜靜地躺著残吩,像睡著了一般。 火紅的嫁衣襯著肌膚如雪倘核。 梳的紋絲不亂的頭發(fā)上世剖,一...
    開封第一講書人閱讀 52,255評論 1 308
  • 那天,我揣著相機與錄音笤虫,去河邊找鬼旁瘫。 笑死,一個胖子當著我的面吹牛琼蚯,可吹牛的內(nèi)容都是我干的酬凳。 我是一名探鬼主播,決...
    沈念sama閱讀 40,825評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼遭庶,長吁一口氣:“原來是場噩夢啊……” “哼宁仔!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起峦睡,我...
    開封第一講書人閱讀 39,729評論 0 276
  • 序言:老撾萬榮一對情侶失蹤翎苫,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后榨了,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體煎谍,經(jīng)...
    沈念sama閱讀 46,271評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,363評論 3 340
  • 正文 我和宋清朗相戀三年龙屉,在試婚紗的時候發(fā)現(xiàn)自己被綠了呐粘。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,498評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡转捕,死狀恐怖作岖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情五芝,我是刑警寧澤痘儡,帶...
    沈念sama閱讀 36,183評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站枢步,受9級特大地震影響沉删,放射性物質(zhì)發(fā)生泄漏蓄坏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,867評論 3 333
  • 文/蒙蒙 一丑念、第九天 我趴在偏房一處隱蔽的房頂上張望涡戳。 院中可真熱鬧,春花似錦脯倚、人聲如沸渔彰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽恍涂。三九已至,卻和暖如春植榕,著一層夾襖步出監(jiān)牢的瞬間再沧,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評論 1 272
  • 我被黑心中介騙來泰國打工尊残, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留炒瘸,地道東北人。 一個月前我還...
    沈念sama閱讀 48,906評論 3 376
  • 正文 我出身青樓寝衫,卻偏偏與公主長得像顷扩,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子慰毅,可洞房花燭夜當晚...
    茶點故事閱讀 45,507評論 2 359

推薦閱讀更多精彩內(nèi)容

  • Ubuntu的發(fā)音 Ubuntu,源于非洲祖魯人和科薩人的語言着饥,發(fā)作 oo-boon-too 的音犀农。了解發(fā)音是有意...
    螢火蟲de夢閱讀 99,357評論 9 467
  • 古代十大兵器排名: 中國古代十大兵器排行第十名:諸葛亮——孔明扇諸葛亮乃是三國時期最偉大的軍事家,神機妙算贱勃,簡直是...
    曉寒深處明月人倚樓閱讀 4,422評論 0 5
  • 我的彩鉛畫從這張雪人拉開帷幕…… 第一幅作品:雪人井赌!應(yīng)該是簡單谤逼,但當時畫了好幾次贵扰,最后出來這個圈還是歪扭~ 第二幅...
    毛丟丟呀毛丟丟閱讀 509評論 0 0
  • 很久很久沒有寫字了。不是不想寫流部,只是不知道從何寫起戚绕。日復一日,年復一年枝冀,天天一成不變的生活舞丛,仿佛行尸走肉般迷茫...
    貓絕閱讀 556評論 0 50
  • 放羊和砍柴的故事告訴我們耘子,面同一件事物,心態(tài)不一樣球切,結(jié)果就會不一樣谷誓! 你是砍柴的,他是放羊的吨凑,你和他聊了一天捍歪,他的...
    沙漠之駱駝刺閱讀 65評論 0 0